diff --git a/.gitignore b/.gitignore index 7398ce4..8aeb7bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ *.pyc *.out *.tmp +*~ +\#* +*.gen +\.\#* +*mail.txt \ No newline at end of file diff --git a/amb.ss b/amb.ss new file mode 100644 index 0000000..7b36b1d --- /dev/null +++ b/amb.ss @@ -0,0 +1,42 @@ +#!r6rs + +(import (rnrs) + (scheme-tools) + (transforms) + (rhash)) + +(define to-explore '()) +(define vals '()) + +(define (flip) + ((call/cc + (lambda (k) + (k (lambda () + (begin + (set! to-explore (cons (lambda (t v) (k (lambda () (begin (set! to-explore t) (set! vals v) #f)))) to-explore)) + #t))))))) + +(define (enumerate proc) + (set! vals (list (proc))) + (let loop () + (if (null? to-explore) + vals + (let* ([proc (car to-explore)] + [val (proc to-explore vals)]) + (set! to-explore (cdr to-explore)) + (set! vals (cons val vals)) + (loop))))) + +(define (my-and a b) + (and a b)) + +(define (my-or a b) + (or a b)) + +(define (recurse n) + (if (= n 0) + (flip) + ((if (= (mod n 2) 0) my-and my-or) + (recurse (- n 1)) (recurse (- n 1))))) + +(pretty-print (enumerate (lambda () (recurse 2)))) diff --git a/cc-wrapper.ss b/cc-wrapper.ss new file mode 100644 index 0000000..aa666e5 --- /dev/null +++ b/cc-wrapper.ss @@ -0,0 +1,19 @@ +#!r6rs + +(import (rnrs) + (scheme-tools) + (transforms)) + +(define (transform expr reserved-words) + (cc-transform + (cps-transform + (assignment-transform + (letrec-to-set + expr)) + reserved-words) + reserved-words)) + +(pretty-print + (transform + '%(expr)s + '(flip))) \ No newline at end of file diff --git a/count-wrapper.ss b/count-wrapper.ss new file mode 100644 index 0000000..bb6f123 --- /dev/null +++ b/count-wrapper.ss @@ -0,0 +1,82 @@ +#!r6rs + +;; Shortcutting enumeration based on continuation hashing + +(import (rnrs) + (scheme-tools) + (transforms) + (rhash)) + +(define (transform expr reserved-words) + (cc-transform + (cps-transform + (assignment-transform + (letrec-to-set + expr)) + reserved-words) + reserved-words)) + +(define (wrap e) + `(begin + (define search-stack '()) + (define history '()) + (define future '()) + (define (raw-flip) + (if (null? future) + (begin + (set! search-stack + (append (list (cons #f history)) + search-stack)) + (set! history (cons #t history)) + #t) + (begin + (let ([v (car future)]) + (set! future (cdr future)) + (set! history (cons v history)) + v)))) + (define count-table (make-hash-table)) + (define value-table (make-hash-table)) + (define (ht-inc! ht k) + (let ([count (hash-table-ref/default ht k 0)]) + (hash-table-set! ht k (+ count 1)))) + (define (enumerate proc) + (set! count-table (make-hash-table)) + (set! search-stack '()) + (set! history '()) + (set! future '()) + (let ([v1 (proc)] + [h1 history]) + (set! history '()) + (let loop ([vals (list (list v1 (reverse h1)))]) + (if (null? search-stack) + vals + (begin + (set! history '()) + (set! future (reverse (car search-stack))) + (set! search-stack (cdr search-stack)) + (let ([v (proc)]) + (loop (cons (list v (reverse history)) vals)))))))) + (define flip + (vector + (lambda (self k) + (let ([flip-val (raw-flip)]) + (ht-inc! count-table (cons flip-val k)) + ((vector-ref k 0) + k + flip-val))))) + (define (my-and a b) + (and a b)) + (define (my-or a b) + (or a b)) + (define print-future pretty-print) + (pretty-print (enumerate (lambda () (begin ,@(cdr e))))) + (pretty-print (map cdr (hash-table->alist count-table))))) + +(define prog + '%(expr)s) + +(define te + (transform prog + '(flip))) + +(pretty-print (wrap te)) \ No newline at end of file diff --git a/count.py b/count.py new file mode 100755 index 0000000..e31b032 --- /dev/null +++ b/count.py @@ -0,0 +1,28 @@ +#!/usr/bin/python +from subprocess import Popen +from external import optfunc + +# enumerate dumbly & print out state counts + +@optfunc.main +def main(fn): + """Usage: %prog [options]""" + # read fn + expr = open(fn).read() + # write temporary file that will pretty-print cc-converted file + count_generator = open("count-wrapper.ss").read() % { "expr" : expr } + f = open("count.gen", "w") + f.write(count_generator) + f.close() + # run temporary file, get output + p = Popen("ikarus --r6rs-script ./count.gen > ./count.tmp", shell=True) + p.communicate() + code = open("count.tmp").read() + # read wrapper template & fill in cc-converted code & write to file + wrapper = open("wrapper.ss").read() + out = open("count.out", "w") + out.write(wrapper % { "code" : code }) + out.close() + # run + p = Popen("ikarus --r6rs-script ./count.out", shell=True) + p.communicate() diff --git a/enumerate-me-2.ss b/enumerate-me-2.ss new file mode 100644 index 0000000..4c52102 --- /dev/null +++ b/enumerate-me-2.ss @@ -0,0 +1,8 @@ +(begin + (define recurse + (lambda (n) + (if (= n 0) + (flip) + ((if (= (mod n 2) 0) my-and my-or) + (recurse (- n 1)) (recurse (- n 1)))))) + (recurse 2)) \ No newline at end of file diff --git a/enumerate-me.ss b/enumerate-me.ss new file mode 100644 index 0000000..66d9740 --- /dev/null +++ b/enumerate-me.ss @@ -0,0 +1 @@ +(list (flip) (flip)) \ No newline at end of file diff --git a/graph-test.ss b/graph-test.ss new file mode 100644 index 0000000..104e026 --- /dev/null +++ b/graph-test.ss @@ -0,0 +1,32 @@ +#!r6rs + +(import (graph) + (rnrs) + (scheme-tools)) + +(define (test) + (begin + (define flip + (vector + (lambda (self k) k) + 'flip-code)) + (define top + (vector + (lambda (self v) + (begin + (display "result: ") + (pretty-print v) + v)) + 'top-code)) + (define (thunk) + ((vector-ref flip 0) + flip + (vector (lambda (self x) ((vector-ref flip 0) + flip + (vector (lambda (self y) ((vector-ref top 0) top (list (vector-ref self 2) y))) + 'l2-code + x))) + 'l1-code))) + (print-graph thunk))) + +(test) \ No newline at end of file diff --git a/graph-wrapper.ss b/graph-wrapper.ss new file mode 100644 index 0000000..03d535a --- /dev/null +++ b/graph-wrapper.ss @@ -0,0 +1,33 @@ +#!r6rs + +(import (graph) + (rnrs) + (rnrs mutable-pairs) + (scheme-tools)) + +(define (my-and a b) + (and a b)) + +(define (my-or a b) + (or a b)) + +(define (thunk) + (begin + (define flip + (vector + (lambda (self k) k) + 'flip-code)) + (define top + (vector + (lambda (self v) + (begin + (display "result: ") + (pretty-print v) + v)) + 'top-code)) + ;; cc code goes here + %(cc_code)s + )) + +(print-graph thunk) + diff --git a/graph.py b/graph.py new file mode 100755 index 0000000..6683ba1 --- /dev/null +++ b/graph.py @@ -0,0 +1,28 @@ +#!/usr/bin/python +from subprocess import Popen +from external import optfunc + +# enumerate smartly & print out context graph + +@optfunc.main +def main(fn): + """Usage: %prog """ + # read fn + expr = open(fn).read() + # write temporary file that will pretty-print cc-converted file + cc_generator = open("cc-wrapper.ss").read() % { "expr" : expr } + f = open("cc.gen", "w") + f.write(cc_generator) + f.close() + # run temporary file, get output + p = Popen("ikarus --r6rs-script ./cc.gen > ./cc.tmp", shell=True) + p.communicate() + cc_code = open("cc.tmp").read() + # read wrapper template & fill in cc-converted code & write to file + graph_generator = open("graph-wrapper.ss").read() % { "cc_code" : cc_code } + f = open("cc.out", "w") + f.write(graph_generator) + f.close() + # run + p = Popen("ikarus --r6rs-script ./cc.out", shell=True) + p.communicate() diff --git a/graph.ss b/graph.ss new file mode 100644 index 0000000..d279b7c --- /dev/null +++ b/graph.ss @@ -0,0 +1,118 @@ +#!r6rs + +;; assumptions: +;; - terminal values are not vectors +;; - all random primitives are fair flips + +;; data types: +;; table: cont -> conns +;; conns: v -> (p . node) +;; [conn-1 conn-2 ...] +;; node: cont | value +;; cont: v -> cont | value + +(library + + (graph) + + (export print-graph) + + (import (rnrs) + (only (_srfi :1) first second) + (scheme-tools) + (transforms) + (rhash)) + + (define-record-type graph + (fields (mutable root graph:root graph:set-root!) + (mutable table graph:table graph:set-table!) + (mutable frontier graph:frontier graph:set-frontier!)) + (protocol + (lambda (p) + (lambda () (p 'empty (make-hash-table) '()))))) + + (define (graph:pop-frontier! graph) + (let ([frontier (graph:frontier graph)]) + (if (null? frontier) + (error graph "tried to pop empty frontier!") + (let ([next (first frontier)]) + (graph:set-frontier! graph (rest frontier)) + next)))) + + (define (graph:push-frontier! graph node) + (graph:set-frontier! graph (pair node (graph:frontier graph)))) + + (define (graph:add-node! graph node) + (let ([node-exists (hash-table-ref/default (graph:table graph) node #f)]) + (when (not node-exists) + (hash-table-set! (graph:table graph) node '()) + (graph:push-frontier! graph node)))) + + (define conn->value first) + + (define conn->score second) + + (define (graph:connect! graph parent child value score) + (let* ([conns (hash-table-ref (graph:table graph) parent)] + [old-conn (assoc value conns)] + [new-conn (pair value (pair score child))]) + (if (false? old-conn) + (hash-table-set! (graph:table graph) + parent + (pair new-conn conns)) + (assert (equal? old-conn new-conn))))) + + (define/curry (graph:add-child! graph node child value score) + (graph:add-node! graph child) + (graph:connect! graph node child value score)) + + (define cont? vector?) + + ;; (node, value) -> node + (define (call node value) + ((vector-ref node 0) node value)) + + (define (get-values node) + (list #t #f)) + + (define (get-scores node) + (list .5 .5)) + + (define (node->graph node) + (let ([graph (make-graph)]) + (graph:add-node! graph node) + (graph:set-root! graph node) + graph)) + + ;; step: graph -> graph + (define (step graph) + (if (null? (graph:frontier graph)) + #f + (let ([node (graph:pop-frontier! graph)]) + (when (cont? node) + (let* ([values (get-values node)] + [scores (get-scores node)] + [nodes (map (lambda (v) (call node v)) values)]) + (for-each (graph:add-child! graph node) nodes values scores))) + graph))) + + ;; explode: graph -> graph + (define (explode graph) + (let ([new-graph (step graph)]) + (if (false? new-graph) + graph + (explode new-graph)))) + + ;; init: thunk -> graph + (define (init thunk) + (node->graph (thunk))) + + (define (print-graph thunk) + (map pretty-print + (finitize + (hash-table->alist + (graph:table + (explode + (init thunk))))))) + + ) \ No newline at end of file diff --git a/rhash.ss b/rhash.ss index e5d513a..f5e4262 100644 --- a/rhash.ss +++ b/rhash.ss @@ -26,14 +26,15 @@ hash-table-walk hash-table-fold hash-table-copy - hash-table-merge!) + hash-table-merge! + finitize) (import (rnrs) (scheme-tools) (transforms) (except (_srfi :69) string-hash string-ci-hash)) - (define (finitize obj) + (define/kw (finitize obj) (define seen '()) (define sym (symbol-maker 's)) (define (fin obj) diff --git a/search.ss b/search.ss new file mode 100644 index 0000000..193db4f --- /dev/null +++ b/search.ss @@ -0,0 +1,32 @@ +#!r6rs + +(import (rnrs) + (scheme-tools) + (transforms) + (rhash)) + +(define (member? obj lst) + (if (null? lst) + #f + (if (equal? (car lst) obj) + #t + (member? obj (cdr lst))))) + +(define (dfs graph) + (helper (list graph) '())) + +(define (helper stack visited) + (if (null? stack) + visited + (let ([currentNode (car stack)]) + (if (member? currentNode visited) + (helper (cdr stack) + visited) + (begin + (pretty-print currentNode) + (helper (append (node->children currentNode) (cdr stack)) + (cons currentNode visited))))))) + +(define node->children cdr) + +(pretty-print (dfs '(1 (8 (2) (3) (4)) (9 (5) (6) (7))))) \ No newline at end of file