• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqtwindows誰得cocoapythonphprubygameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

A categorical programming language


Commit MetaInfo

修订版83402fcc7add55f224434c3f7938d765977e2415 (tree)
时间2022-09-12 01:49:26
作者Corbin <cds@corb...>
CommiterCorbin

Log Message

Check in a bunch of random files that I've had sitting around.

更改概述

差异

--- /dev/null
+++ b/.envrc
@@ -0,0 +1,5 @@
1+# export NIX_PATH=nixpkgs=/home/simpson/nixpkgs
2+use nix
3+eval $(keychain --eval --agents ssh)
4+
5+# export CAMMY_HIVE="$(pwd)/hive/"
--- a/honey.yaml
+++ b/honey.yaml
@@ -8,6 +8,7 @@ components:
88 type: string
99 Token:
1010 type: integer
11+ format: int64
1112 Functor:
1213 type: array
1314 items:
--- /dev/null
+++ b/jellyserver.py
@@ -0,0 +1,79 @@
1+#!/usr/bin/env nix-shell
2+#! nix-shell -i python3 -p python3
3+
4+# This is a simple HTTP service written in Python 3. It exposes jelly to the
5+# network by allowing requests to implicitly call jelly via an opaque
6+# membrane. The quality of jelly is not guaranteed.
7+
8+import hashlib
9+import http.server
10+import json
11+import urllib.parse
12+import sys
13+import threading
14+
15+# Expressions are stored in cache, rather than durable storage. The current
16+# storage is a dict protected by a reader-writer lock.
17+
18+cache = {}
19+cacheLock = threading.Lock()
20+
21+# Expressions are keyed by unguessable tokens.
22+
23+def makeToken(expr):
24+ return hashlib.sha256(expr).hexdigest()
25+TOKEN_LENGTH = len(makeToken(b"id"))
26+
27+class JellyHandler(http.server.BaseHTTPRequestHandler):
28+
29+ # All responses will be valid JSON.
30+
31+ def finish_JSON(self, value):
32+ encoded = json.dumps(value).encode("utf-8")
33+ self.send_response(http.server.HTTPStatus.OK)
34+ self.send_header("Content-Type", "application/json")
35+ self.send_header("Content-Length", len(encoded))
36+ self.end_headers()
37+ self.wfile.write(encoded)
38+
39+ # When a token is requested, look for an equivalent expression.
40+
41+ def do_GET(self):
42+ url = urllib.parse.urlparse(self.path)
43+ # Remove the leading slash.
44+ key = url.path[1:]
45+ if len(key) != TOKEN_LENGTH:
46+ self.send_error(http.server.HTTPStatus.NOT_FOUND)
47+ return
48+
49+ try:
50+ # XXX timing attacks happen here
51+ with cacheLock:
52+ expr = cache[key]
53+ except KeyError:
54+ self.send_error(http.server.HTTPStatus.NOT_FOUND)
55+ return
56+
57+ self.finish_JSON(expr)
58+
59+ def do_PUT(self):
60+ exprLength = int(self.headers.get("Content-Length"))
61+ expr = self.rfile.read(exprLength)
62+ decoded = expr.decode("utf-8")
63+ key = makeToken(expr)
64+ with cacheLock:
65+ cache[key] = decoded
66+
67+ self.finish_JSON(key)
68+
69+PORT = 8000
70+
71+def main():
72+ print("Token length is %d" % TOKEN_LENGTH, file=sys.stderr)
73+ print("Starting HTTP server on port %d" % PORT, file=sys.stderr)
74+ server = http.server.ThreadingHTTPServer(("", PORT), JellyHandler)
75+ server.serve_forever()
76+ return 0
77+
78+if __name__ == "__main__":
79+ sys.exit(main())
--- /dev/null
+++ b/proof.txt
@@ -0,0 +1,30 @@
1+What's the smallest expression implementing nat/add?
2+
3+nat/add : N × N → N
4+
5+Must be uncurried from primitive recursion:
6+
7+(curry nat/add) = (pr X F) : N → [N, N]
8+X : 1 → [N, N]
9+F : [N, N] → [N, N]
10+
11+Forall n, 0 + n = n, so:
12+
13+(comp (pair zero id) nat/add) = id : N → N
14+
15+This means that X must name a function N → N which sends every n to n:
16+
17+X = (name id) = (curry snd) : 1 → [N, N]
18+
19+F must be uncurried:
20+
21+(uncurry F) : [N, N] × N → N
22+
23+We need to apply and +1. This is the smallest way to do that:
24+
25+(comp app succ) = (comp (uncurry id) succ) : [N, N] × N → N
26+
27+So:
28+
29+(uncurry F) = (comp app succ) : [N, N] × N → N
30+F = (curry (comp app succ)) : [N, N] → [N, N]
--- /dev/null
+++ b/ski2cammy.py
@@ -0,0 +1,36 @@
1+#!/usr/bin/env python3
2+# nix-shell -i python3 -p python3
3+
4+# A simple parser and translator from SKI combinator calculus to Cammy.
5+# Well-formedness of input and well-typedness of output are not enforced.
6+
7+def parse(expr):
8+ stack = [[]]
9+ for char in expr:
10+ if char == "(":
11+ stack.append([])
12+ elif char == ")":
13+ row = stack.pop()
14+ stack[-1].append(row)
15+ elif char in "SKIBCW":
16+ stack[-1].append(char)
17+ return stack[-1]
18+
19+expr = parse("S(K(S(S K K)(S K K)))(S(S(K S)(S(K K)(S K K)))(K(S(S K K)(S K K))))")
20+
21+print(expr)
22+
23+templates = {
24+ "K": "(curry fst)",
25+ "S": "(curry (curry (comp (pair (comp (pair (comp fst fst) snd) app) (comp (pair (comp fst snd) snd) app)) app)))",
26+}
27+
28+def translate(tree):
29+ if isinstance(tree, str):
30+ return templates[tree]
31+ else:
32+ # Trust input; don't check arity.
33+ expr = translate(tree[0])
34+ for t in tree[1:]:
35+ expr = "(comp (pair %s %s) app)" % (expr, translate(t))
36+ return expr
Binary files /dev/null and b/wallpapers/burning-ship-color.png differ
Binary files /dev/null and b/wallpapers/burning-ship.png differ