diff options
author | Marvin Borner | 2024-11-05 22:54:29 +0100 |
---|---|---|
committer | Marvin Borner | 2024-11-05 22:54:29 +0100 |
commit | db8a8639bc1ecb6834b829370e3aba874b00d95b (patch) | |
tree | 714de7ae1b9a13f14ad6753dc8a5858453c0240c | |
parent | 0041afc9c49e1e82def7850c38056a354b24de6f (diff) |
Default to left associative applications
-rw-r--r-- | index.html | 197 | ||||
-rw-r--r-- | main.js | 32 |
2 files changed, 122 insertions, 107 deletions
@@ -28,13 +28,13 @@ bl = \\0 br = \\0 -- two abstractions to ignore the screen state and replace the entire screen -\\((((0 tl) tr) bl) br)" +\\(0 tl tr bl br)" > Just black </option> <option - value="map = \\(0 \\\\\((((0 (6 4)) (6 3)) (6 2)) (6 1))) -invert = \\\((2 0) 1) + value="map = \\(0 \\\\\(0 (6 4) (6 3) (6 2) (6 1))) +invert = \\\(2 0 1) -- the first argument is the empty screen, therefore we can use point-free style (map invert)" @@ -42,152 +42,152 @@ invert = \\\((2 0) 1) Invert </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -\(y \\((((0 1) \\1) \\0) 1))" + value="y = \(\(0 0) \(1 (0 0))) +\(y \\(0 1 \\1 \\0 1))" > Diagonal </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = (y \\((((0 1) \\0) \\0) 1)) + value="y = \(\(0 0) \(1 (0 0))) +tl = (y \\(0 1 \\0 \\0 1)) tr = \\0 -bl = (y \\((((0 \\0) 1) 1) \\0)) -br = (y \\((((0 1) \\0) \\0) 1)) -\\((((0 tl) tr) bl) br)" +bl = (y \\(0 \\0 1 1 \\0)) +br = (y \\(0 1 \\0 \\0 1)) +\\(0 tl tr bl br)" > Lambda </option> <option value="-- note how no white gets drawn since the highlighted parts would be infinitely detailed -y = \(\(1 (0 0)) \(1 (0 0))) -\(y \\((((0 1) \\0) 1) 1))" +y = \(\(0 0) \(1 (0 0))) +\(y \\(0 1 \\0 1 1))" > Sierpiński triangle </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = (y \\((((0 \\0) 1) 1) 1)) -tr = (y \\((((0 1) \\0) 1) 1)) -bl = (y \\((((0 1) 1) \\0) 1)) -br = (y \\((((0 1) 1) 1) \\0)) -\\((((0 tl) tr) bl) br)" + value="y = \(\(0 0) \(1 (0 0))) +tl = (y \\(0 \\0 1 1 1)) +tr = (y \\(0 1 \\0 1 1)) +bl = (y \\(0 1 1 \\0 1)) +br = (y \\(0 1 1 1 \\0)) +\\(0 tl tr bl br)" > Sierpiński square </option> <option value="y = \(\(0 0) \(1 (0 0))) -sa = (y \\((((0 \\0) 1) 1) 1)) -sb = (y \\((((0 1) \\0) 1) 1)) -sc = (y \\((((0 1) 1) \\0) 1)) -sd = (y \\((((0 1) 1) 1) \\0)) -tl = \\\\\((((0 4) 3) 2) sd) -tr = \\\\\((((0 4) 3) sc) 1) -bl = \\\\\((((0 4) sb) 2) 1) -br = \\\\\((((0 sa) 3) 2) 1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" +sa = (y \\(0 \\0 1 1 1)) +sb = (y \\(0 1 \\0 1 1)) +sc = (y \\(0 1 1 \\0 1)) +sd = (y \\(0 1 1 1 \\0)) +tl = \\\\\(0 4 3 2 sd) +tr = \\\\\(0 4 3 sc 1) +bl = \\\\\(0 4 sb 2 1) +br = \\\\\(0 sa 3 2 1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Sierpiń-T-square v1 </option> <option value="y = \(\(0 0) \(1 (0 0))) -oncesa = (y \\((((0 \\0) 1) 1) 1)) -oncesb = (y \\((((0 1) \\0) 1) 1)) -oncesc = (y \\((((0 1) 1) \\0) 1)) -oncesd = (y \\((((0 1) 1) 1) \\0)) -sa = (y \\((((0 \\0) 1) 1) oncesd)) -sb = (y \\((((0 1) \\0) oncesc) 1)) -sc = (y \\((((0 1) oncesb) \\0) 1)) -sd = (y \\((((0 oncesa) 1) 1) \\0)) -tl = \\\\\((((0 4) 3) 2) sd) -tr = \\\\\((((0 4) 3) sc) 1) -bl = \\\\\((((0 4) sb) 2) 1) -br = \\\\\((((0 sa) 3) 2) 1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" +oncesa = (y \\(0 \\0 1 1 1)) +oncesb = (y \\(0 1 \\0 1 1)) +oncesc = (y \\(0 1 1 \\0 1)) +oncesd = (y \\(0 1 1 1 \\0)) +sa = (y \\(0 \\0 1 1 oncesd)) +sb = (y \\(0 1 \\0 oncesc 1)) +sc = (y \\(0 1 oncesb \\0 1)) +sd = (y \\(0 oncesa 1 1 \\0)) +tl = \\\\\(0 4 3 2 sd) +tr = \\\\\(0 4 3 sc 1) +bl = \\\\\(0 4 sb 2 1) +br = \\\\\(0 sa 3 2 1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Sierpiń-T-square v2 </option> <option value="y = \(\(0 0) \(1 (0 0))) -oncesa = (y \\((((0 \\0) 1) 1) 1)) -oncesb = (y \\((((0 1) \\0) 1) 1)) -oncesc = (y \\((((0 1) 1) \\0) 1)) -oncesd = (y \\((((0 1) 1) 1) \\0)) -sa = ((y \\((((0 \\0) 1) 1) 1)) \\\\\((((0 oncesd) 3) 2) 1)) -sb = ((y \\((((0 1) \\0) 1) 1)) \\\\\((((0 4) oncesc) 2) 1)) -sc = ((y \\((((0 1) 1) \\0) 1)) \\\\\((((0 4) 3) oncesb) 1)) -sd = ((y \\((((0 1) 1) 1) \\0)) \\\\\((((0 4) 3) 2) oncesa)) -tl = \\\\\((((0 4) 3) 2) sa) -tr = \\\\\((((0 4) 3) sb) 1) -bl = \\\\\((((0 4) sc) 2) 1) -br = \\\\\((((0 sd) 3) 2) 1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" +oncesa = (y \\(0 \\0 1 1 1)) +oncesb = (y \\(0 1 \\0 1 1)) +oncesc = (y \\(0 1 1 \\0 1)) +oncesd = (y \\(0 1 1 1 \\0)) +sa = (y \\(0 \\0 1 1 1) \\\\\(0 oncesd 3 2 1)) +sb = (y \\(0 1 \\0 1 1) \\\\\(0 4 oncesc 2 1)) +sc = (y \\(0 1 1 \\0 1) \\\\\(0 4 3 oncesb 1)) +sd = (y \\(0 1 1 1 \\0) \\\\\(0 4 3 2 oncesa)) +tl = \\\\\(0 4 3 2 sa) +tr = \\\\\(0 4 3 sb 1) +bl = \\\\\(0 4 sc 2 1) +br = \\\\\(0 sd 3 2 1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Sierpiń-T-square v3 </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = \\\\\((((0 4) 3) 2) \((((0 \((((0 \\0) \\1) \\1) \\1)) \\1) \\1) \\0)) -tr = \\\\\((((0 4) 3) \((((0 \\1) \((((0 \\1) \\0) \\1) \\1)) \\0) \\1)) 1) -bl = \\\\\((((0 4) \((((0 \\1) \\0) \((((0 \\1) \\1) \\0) \\1)) \\1)) 2) 1) -br = \\\\\((((0 \((((0 \\0) \\1) \\1) \((((0 \\1) \\1) \\1) \\0))) 3) 2) 1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" + value="y = \(\(0 0) \(1 (0 0))) +tl = \\\\\(0 4 3 2 \(0 \(0 \\0 \\1 \\1 \\1) \\1 \\1 \\0)) +tr = \\\\\(0 4 3 \(0 \\1 \(0 \\1 \\0 \\1 \\1) \\0 \\1) 1) +bl = \\\\\(0 4 \(0 \\1 \\0 \(0 \\1 \\1 \\0 \\1) \\1) 2 1) +br = \\\\\(0 \(0 \\0 \\1 \\1 \(0 \\1 \\1 \\1 \\0)) 3 2 1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Sierpiński carpet (variant) </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = \\\\\((((0 4) 3) 2) \\0) -tr = \\\\\((((0 4) 3) \\0) 1) -bl = \\\\\((((0 4) \\0) 2) 1) -br = \\\\\((((0 \\0) 3) 2) 1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" + value="y = \(\(0 0) \(1 (0 0))) +tl = \\\\\(0 4 3 2 \\0) +tr = \\\\\(0 4 3 \\0 1) +bl = \\\\\(0 4 \\0 2 1) +br = \\\\\(0 \\0 3 2 1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > T-square </option> <option value="-- variation of T-Square, mostly unrelated to Koch snowflakes -y = \(\(1 (0 0)) \(1 (0 0))) -tl = \\\\\((((0 \\1) 3) 2) 1) -tr = \\\\\((((0 4) \\1) 2) 1) -bl = \\\\\((((0 4) 3) \\1) 1) -br = \\\\\((((0 4) 3) 2) \\1) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" +y = \(\(0 0) \(1 (0 0))) +tl = \\\\\(0 \\1 3 2 1) +tr = \\\\\(0 4 \\1 2 1) +bl = \\\\\(0 4 3 \\1 1) +br = \\\\\(0 4 3 2 \\1) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Snowflake </option> <option value="s=\\0 -quad = \\((((0 1) 1) 1) 1) -y = \(\(1 (0 0)) \(1 (0 0))) -\(y \\((((0 (quad \((((0 2) s) s) s))) (quad \((((0 s) 2) s) s))) (quad \((((0 s) s) 2) s))) (quad \((((0 s) s) s) 2))))" +quad = \\(0 1 1 1 1) +y = \(\(0 0) \(1 (0 0))) +\(y \\(0 (quad \(0 2 s s s)) (quad \(0 s 2 s s)) (quad \(0 s s 2 s)) (quad \(0 s s s 2))))" > Cantor dust </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = \\\\\(y \((((1 \\1) 2) \\0) 5)) -tr = \\\\\(y \((((1 3) \\0) 4) \\1)) -bl = \\\\\(y \((((1 \\1) 3) \\0) 4)) -br = \\\\\(y \((((1 2) \\0) 5) \\1)) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" + value="y = \(\(0 0) \(1 (0 0))) +tl = \\\\\(y \(1 \\1 2 \\0 5)) +tr = \\\\\(y \(1 3 \\0 4 \\1)) +bl = \\\\\(y \(1 \\1 3 \\0 4)) +br = \\\\\(y \(1 2 \\0 5 \\1)) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Squiggly Cross </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -tl = \\\\(y \\((((0 \((((0 \\0) 4) 5) 6)) 1) 1) \\1)) -tr = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \\1) 1)) -bl = \\\\(y \\((((0 1) \\1) \((((0 3) 4) \\0) 6)) 1)) -br = \\\\(y \\((((0 \\1) 1) 1) \((((0 3) 4) 5) \\0))) -\(y \\((((0 (1 tl)) (1 tr)) (1 bl)) (1 br)))" + value="y = \(\(0 0) \(1 (0 0))) +tl = \\\\(y \\(0 \(0 \\0 4 5 6) 1 1 \\1)) +tr = \\\\(y \\(0 1 \(0 3 \\0 5 6) \\1 1)) +bl = \\\\(y \\(0 1 \\1 \(0 3 4 \\0 6) 1)) +br = \\\\(y \\(0 \\1 1 1 \(0 3 4 5 \\0))) +\(y \\(0 (1 tl) (1 tr) (1 bl) (1 br)))" > Sunrise </option> <option - value="y = \(\(1 (0 0)) \(1 (0 0))) -a = \\\\(y \\((((0 \((((0 \\0) 4) 5) 6)) 1) 1) \((((0 3) 4) 5) \\0))) -b = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \((((0 3) 4) \\0) 6)) 1)) -\(y \\((((0 (1 a)) (1 b)) (1 b)) (1 a)))" + value="y = \(\(0 0) \(1 (0 0))) +a = \\\\(y \\(0 \(0 \\0 4 5 6) 1 1 \(0 3 4 5 \\0))) +b = \\\\(y \\(0 1 \(0 3 \\0 5 6) \(0 3 4 \\0 6) 1)) +\(y \\(0 (1 a) (1 b) (1 b) (1 a))" > Recursive Nonsense </option> @@ -196,21 +196,20 @@ b = \\\\(y \\((((0 1) \((((0 3) \\0) 5) 6)) \((((0 3) 4) \\0) 6)) 1)) w = \\1 b = \\0 isw = \0 -isb = \((0 b) w) -invert = \\\((2 0) 1) +isb = \(0 b w) +invert = \\\(2 0 1) build = \\\\\((((0 4) 3) 2) 1) -empty = ((((build b) b) b) b) +empty = (build b b b b) tl = \\\\3 tr = \\\\2 bl = \\\\1 br = \\\\0 get = \\(0 1) -settl = \\(1 \\\\\((((0 5) 3) 2) 1)) -settr = \\(1 \\\\\((((0 4) 5) 2) 1)) -setbl = \\(1 \\\\\((((0 4) 3) 5) 1)) -setbr = \\(1 \\\\\((((0 4) 3) 2) 5)) -map = \\(0 \\\\\((((0 (6 4)) (6 3)) (6 2)) (6 1))) -qsplit = \(0 \\\\\((((0 ((4 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((3 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((2 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0))) ((1 \((((0 \\1) \\1) \\1) \\1)) \((((0 \\0) \\0) \\0) \\0)))) +settl = \\(1 \\\\\(0 5 3 2 1)) +settr = \\(1 \\\\\(0 4 5 2 1)) +setbl = \\(1 \\\\\(0 4 3 5 1)) +setbr = \\(1 \\\\\(0 4 3 2 5)) +map = \\(0 \\\\\(0 (6 4) (6 3) (6 2) (6 1))) \0" > Template @@ -137,6 +137,20 @@ const isOpen = (t) => { }; const parseLam = (str) => { + // default to left-associative application + const folded = (s) => { + const init = parseLam(s); + if (!init[1] || ")]".includes(init[1][0])) return init; + + const go = (acc, rst) => { + const parsed = parseLam(rst); + const chain = app(acc)(parsed[0]); + if (!parsed[1] || ")]".includes(parsed[1][0])) return [chain, parsed[1]]; + return go(chain, parsed[1]); + }; + return go(init[0], init[1]); + }; + if (!str) { error("in parseLam"); return [{}, ""]; @@ -148,17 +162,19 @@ const parseLam = (str) => { case "\\": case "[": // bruijn const [body, _tail] = parseLam(tail.trim()); - return [abs(body), head == "[" ? _tail.trim().slice(1) : _tail.trim()]; + return [ + abs(body), + head == "[" ? _tail.trim().slice(1).trim() : _tail.trim(), + ]; case "(": - const [left, tail1] = parseLam(tail); - const [right, tail2] = parseLam(tail1.trim()); - return [app(left)(right), tail2.trim().slice(1)]; + const [chain, _tail1] = folded(tail.trim()); + return [chain, _tail1.trim().slice(1).trim()]; case ")": case "]": error("in parseLam"); return []; default: - if (head == " ") return parseLam(tail); + if (head == " ") return folded(tail); if (head >= "a" && head <= "z") { // substitution let name = ""; @@ -166,7 +182,7 @@ const parseLam = (str) => { name += str[0]; str = str.slice(1); } - return [def(name), str]; + return [def(name), str.trim()]; } else { // de Bruijn index let num = ""; @@ -174,7 +190,7 @@ const parseLam = (str) => { num += str[0]; str = str.slice(1); } - return [idx(parseInt(num)), str]; + return [idx(parseInt(num)), str.trim()]; } } }; @@ -511,6 +527,6 @@ const reduceLoop = (worker, root, _t) => { function helpSyntax() { alert( - "The syntax uses standard notations for de Bruijn indexed lambda calculus. The de Bruijn indices start at 0. You can use `\\`, `λ`, or `[..]` for abstractions. Applications use parenthesis and currently do *not* assume left associativity by default. All terms can also be replaced by a string of binary lambda calculus (BLC) - useful if you're not comfortable with de Bruijn indices (e.g. by using John Tromp's `lam` compiler).\nYou can define substitutions (like in the presets) using `=`.\n\nHave fun!", + "The syntax uses standard notations for de Bruijn indexed lambda calculus. The de Bruijn indices start at 0. You can use `\\`, `λ`, or `[..]` for abstractions. Applications use parenthesis and assume left associativity by default. All terms can also be replaced by a string of binary lambda calculus (BLC) - useful if you're not comfortable with de Bruijn indices (e.g. by using John Tromp's `lam` compiler).\nYou can define substitutions (like in the presets) using `=`.\n\nHave fun!", ); } |