From d615bccb08274398f347b78a1dd746fe40eb3671 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 27 Jul 2006 19:32:22 +0000 Subject: [PATCH] collect benchmark programs together in one place, finally svn: r3848 --- .../mzscheme/benchmarks/common/README.txt | 8 + .../mzscheme/benchmarks/common/browse.sch | 179 + .../mzscheme/benchmarks/common/conform.sch | 619 +++ .../mzscheme/benchmarks/common/conform.ss | 2 + .../mzscheme/benchmarks/common/cpstack.sch | 34 + .../mzscheme/benchmarks/common/cpstack.ss | 2 + .../tests/mzscheme/benchmarks/common/ctak.sch | 55 + .../tests/mzscheme/benchmarks/common/ctak.ss | 2 + .../mzscheme/benchmarks/common/dderiv.ss | 99 + .../mzscheme/benchmarks/common/deriv.sch | 59 + .../tests/mzscheme/benchmarks/common/deriv.ss | 2 + .../mzscheme/benchmarks/common/destruct.sch | 64 + .../mzscheme/benchmarks/common/destruct.ss | 2 + .../tests/mzscheme/benchmarks/common/div.ss | 54 + .../benchmarks/common/dynamic-input.txt.gz | Bin 0 -> 209619 bytes .../mzscheme/benchmarks/common/dynamic.sch | 2340 ++++++++++ .../mzscheme/benchmarks/common/dynamic.ss | 2 + .../mzscheme/benchmarks/common/earley.sch | 650 +++ .../mzscheme/benchmarks/common/earley.ss | 2 + .../tests/mzscheme/benchmarks/common/fft.sch | 117 + .../tests/mzscheme/benchmarks/common/fft.ss | 2 + .../mzscheme/benchmarks/common/graphs.sch | 645 +++ .../mzscheme/benchmarks/common/graphs.ss | 2 + .../mzscheme/benchmarks/common/nboyer.sch | 759 ++++ .../mzscheme/benchmarks/common/nboyer.ss | 2 + .../tests/mzscheme/benchmarks/common/nfa.sch | 48 + .../tests/mzscheme/benchmarks/common/nfa.ss | 2 + .../mzscheme/benchmarks/common/nucleic2.sch | 3759 +++++++++++++++++ .../mzscheme/benchmarks/common/nucleic2.ss | 2 + .../mzscheme/benchmarks/common/puzzle.sch | 169 + .../mzscheme/benchmarks/common/puzzle.ss | 2 + .../mzscheme/benchmarks/common/sboyer.sch | 774 ++++ .../mzscheme/benchmarks/common/sboyer.ss | 2 + .../mzscheme/benchmarks/common/sort1.sch | 143 + .../tests/mzscheme/benchmarks/common/sort1.ss | 2 + .../tests/mzscheme/benchmarks/common/tak.sch | 25 + .../tests/mzscheme/benchmarks/common/tak.ss | 2 + .../tests/mzscheme/benchmarks/common/takl.sch | 41 + .../tests/mzscheme/benchmarks/common/takl.ss | 2 + .../tests/mzscheme/benchmarks/common/takr.sch | 521 +++ .../tests/mzscheme/benchmarks/common/takr.ss | 2 + .../mzscheme/benchmarks/common/traverse.sch | 158 + .../mzscheme/benchmarks/common/triangle.sch | 84 + .../mzscheme/benchmarks/common/triangle.ss | 2 + .../tests/mzscheme/benchmarks/common/wrap.ss | 7 + .../mzscheme/benchmarks/mz/expand-class.scm | 11 + .../tests/mzscheme/benchmarks/mz/input.xml | 12 + .../tests/mzscheme/benchmarks/mz/parsing.scm | 43 + .../tests/mzscheme/benchmarks/mz/redsem.scm | 6 + .../tests/mzscheme/benchmarks/mz/ssax.scm | 8 + .../mzscheme/benchmarks/shootout/README.txt | 4 + .../mzscheme/benchmarks/shootout/ackermann.ss | 13 + .../tests/mzscheme/benchmarks/shootout/ary.ss | 21 + .../benchmarks/shootout/binarytrees.ss | 45 + .../mzscheme/benchmarks/shootout/chameneos.ss | 55 + .../benchmarks/shootout/cheapconcurrency.ss | 24 + .../mzscheme/benchmarks/shootout/echo.ss | 45 + .../mzscheme/benchmarks/shootout/except.ss | 36 + .../mzscheme/benchmarks/shootout/fannkuch.ss | 86 + .../mzscheme/benchmarks/shootout/fasta.ss | 119 + .../mzscheme/benchmarks/shootout/fibo.ss | 13 + .../mzscheme/benchmarks/shootout/hash.ss | 18 + .../mzscheme/benchmarks/shootout/hash2.ss | 25 + .../mzscheme/benchmarks/shootout/heapsort.ss | 74 + .../mzscheme/benchmarks/shootout/lists.ss | 43 + .../benchmarks/shootout/mandelbrot.ss | 80 + .../mzscheme/benchmarks/shootout/matrix.ss | 76 + .../mzscheme/benchmarks/shootout/moments.ss | 72 + .../mzscheme/benchmarks/shootout/nbody.ss | 166 + .../benchmarks/shootout/nestedloop.ss | 18 + .../mzscheme/benchmarks/shootout/nsieve.ss | 50 + .../benchmarks/shootout/nsievebits.ss | 66 + .../benchmarks/shootout/partialsums.ss | 70 + .../mzscheme/benchmarks/shootout/pidigits.ss | 46 + .../mzscheme/benchmarks/shootout/pidigits1.ss | 57 + .../mzscheme/benchmarks/shootout/random.ss | 40 + .../mzscheme/benchmarks/shootout/recursive.ss | 65 + .../benchmarks/shootout/regexmatch.ss | 59 + .../mzscheme/benchmarks/shootout/regexpdna.ss | 105 + .../benchmarks/shootout/reversecomplement.ss | 60 + .../benchmarks/shootout/reversefile.ss | 13 + .../tests/mzscheme/benchmarks/shootout/run.ss | 54 + .../mzscheme/benchmarks/shootout/sieve.ss | 25 + .../benchmarks/shootout/spellcheck.ss | 23 + .../mzscheme/benchmarks/shootout/strcat.ss | 35 + .../mzscheme/benchmarks/shootout/sumcol.ss | 10 + .../tests/mzscheme/benchmarks/shootout/wc.ss | 18 + .../mzscheme/benchmarks/shootout/wordfreq.ss | 32 + 88 files changed, 13390 insertions(+) create mode 100644 collects/tests/mzscheme/benchmarks/common/README.txt create mode 100644 collects/tests/mzscheme/benchmarks/common/browse.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/conform.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/conform.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/cpstack.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/cpstack.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/ctak.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/ctak.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/dderiv.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/deriv.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/deriv.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/destruct.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/destruct.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/div.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/dynamic-input.txt.gz create mode 100644 collects/tests/mzscheme/benchmarks/common/dynamic.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/dynamic.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/earley.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/earley.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/fft.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/fft.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/graphs.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/graphs.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/nboyer.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/nboyer.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/nfa.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/nfa.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/nucleic2.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/nucleic2.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/puzzle.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/puzzle.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/sboyer.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/sboyer.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/sort1.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/sort1.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/tak.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/tak.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/takl.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/takl.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/takr.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/takr.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/traverse.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/triangle.sch create mode 100644 collects/tests/mzscheme/benchmarks/common/triangle.ss create mode 100644 collects/tests/mzscheme/benchmarks/common/wrap.ss create mode 100644 collects/tests/mzscheme/benchmarks/mz/expand-class.scm create mode 100644 collects/tests/mzscheme/benchmarks/mz/input.xml create mode 100644 collects/tests/mzscheme/benchmarks/mz/parsing.scm create mode 100644 collects/tests/mzscheme/benchmarks/mz/redsem.scm create mode 100644 collects/tests/mzscheme/benchmarks/mz/ssax.scm create mode 100644 collects/tests/mzscheme/benchmarks/shootout/README.txt create mode 100644 collects/tests/mzscheme/benchmarks/shootout/ackermann.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/ary.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/binarytrees.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/chameneos.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/cheapconcurrency.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/echo.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/except.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/fannkuch.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/fasta.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/fibo.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/hash.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/hash2.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/heapsort.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/lists.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/matrix.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/moments.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/nbody.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/nestedloop.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/nsieve.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/nsievebits.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/partialsums.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/pidigits.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/pidigits1.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/random.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/recursive.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/regexmatch.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/regexpdna.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/reversecomplement.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/reversefile.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/run.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/sieve.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/spellcheck.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/strcat.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/sumcol.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/wc.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/wordfreq.ss diff --git a/collects/tests/mzscheme/benchmarks/common/README.txt b/collects/tests/mzscheme/benchmarks/common/README.txt new file mode 100644 index 0000000000..583756b37c --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/README.txt @@ -0,0 +1,8 @@ +Bechmarks obtained from + http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/scheme/code/bench/gabriel/ + http://www.ccs.neu.edu/home/will/GC/sourcecode.html + +Files that end in ".sch" are supposed to be standard Scheme plus `time'. +Files that end in ".ss" are MzScheme wrapper modules. + +Unpack "dynamic-input.txt.gz" if you want to run the "dynamic" benchmark. diff --git a/collects/tests/mzscheme/benchmarks/common/browse.sch b/collects/tests/mzscheme/benchmarks/common/browse.sch new file mode 100644 index 0000000000..834966c64a --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/browse.sch @@ -0,0 +1,179 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: browse.sch +; Description: The BROWSE benchmark from the Gabriel tests +; Author: Richard Gabriel +; Created: 8-Apr-85 +; Modified: 14-Jun-85 18:44:49 (Bob Shaw) +; 16-Aug-87 (Will Clinger) +; 22-Jan-88 (Will Clinger) +; Language: Scheme (but see notes below) +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Note: This benchmark has been run only in implementations in which +; the empty list is the same as #f, and may not work if that is not true. +; Note: This benchmark uses property lists. The procedures that must +; be supplied are get and put, where (put x y z) is equivalent to Common +; Lisp's (setf (get x y) z). +; Note: The Common Lisp version assumes that eq works on characters, +; which is not a portable assumption but is true in most implementations. +; This translation makes the same assumption about eq?. +; Note: The gensym procedure was left as in Common Lisp. Most Scheme +; implementations have something similar internally. +; Note: The original benchmark took the car or cdr of the empty list +; 14,600 times. Before explicit tests were added to protect the offending +; calls to car and cdr, MacScheme was spending a quarter of its run time +; in the exception handler recovering from those errors. + +; The next few definitions should be omitted if the Scheme implementation +; already provides them. + +(module browse mzscheme + +(define (my-append! x y) + (if (null? x) + y + (do ((a x b) + (b (cdr x) (cdr b))) + ((null? b) + (set-cdr! a y) + x)))) + +(define (copy-tree x) + (if (not (pair? x)) + x + (cons (copy-tree (car x)) + (copy-tree (cdr x))))) + +;;; BROWSE -- Benchmark to create and browse through +;;; an AI-like data base of units. + +;;; n is # of symbols +;;; m is maximum amount of stuff on the plist +;;; npats is the number of basic patterns on the unit +;;; ipats is the instantiated copies of the patterns + +(define *rand* 21) + +(define (init n m npats ipats) + (let ((ipats (copy-tree ipats))) + (do ((p ipats (cdr p))) + ((null? (cdr p)) (set-cdr! p ipats))) + (do ((n n (- n 1)) + (i m (cond ((zero? i) m) + (else (- i 1)))) + (name (gensym) (gensym)) + (a #f)) + ((= n 0) a) + (set! a (cons name a)) + (do ((i i (- i 1))) + ((zero? i)) + (put name (gensym) #f)) + (put name + 'pattern + (do ((i npats (- i 1)) + (ipats ipats (cdr ipats)) + (a '())) + ((zero? i) a) + (set! a (cons (car ipats) a)))) + (do ((j (- m i) (- j 1))) + ((zero? j)) + (put name (gensym) #f))))) + +(define (browse-random) + (set! *rand* (remainder (* *rand* 17) 251)) + *rand*) + +(define (randomize l) + (do ((a '())) + ((null? l) a) + (let ((n (remainder (browse-random) (length l)))) + (cond ((zero? n) + (set! a (cons (car l) a)) + (set! l (cdr l)) + l) + (else + (do ((n n (- n 1)) + (x l (cdr x))) + ((= n 1) + (set! a (cons (cadr x) a)) + (set-cdr! x (cddr x)) + x))))))) + +(define (match pat dat alist) + (cond ((null? pat) + (null? dat)) + ((null? dat) '()) + ((or (eq? (car pat) '?) + (eq? (car pat) + (car dat))) + (match (cdr pat) (cdr dat) alist)) + ((eq? (car pat) '*) + (or (match (cdr pat) dat alist) + (match (cdr pat) (cdr dat) alist) + (match pat (cdr dat) alist))) + (else (cond ((not (pair? (car pat))) + (cond ((eq? (string-ref (symbol->string (car pat)) 0) + #\?) + (let ((val (assv (car pat) alist))) + (cond (val (match (cons (cdr val) + (cdr pat)) + dat alist)) + (else (match (cdr pat) + (cdr dat) + (cons (cons (car pat) + (car dat)) + alist)))))) + ((eq? (string-ref (symbol->string (car pat)) 0) + #\*) + (let ((val (assv (car pat) alist))) + (cond (val (match (append (cdr val) + (cdr pat)) + dat alist)) + (else + (do ((l '() + (my-append! l + (cons (if (null? d) + '() + (car d)) + '()))) + (e (cons '() dat) (cdr e)) + (d dat (if (null? d) '() (cdr d)))) + ((or (null? e) + (match (cdr pat) + d + (cons + (cons (car pat) l) + alist))) + (if (null? e) #f #t))))))))) + (else (and + (pair? (car dat)) + (match (car pat) + (car dat) alist) + (match (cdr pat) + (cdr dat) alist))))))) + +(define (browse) + (investigate + (randomize + (init 100 10 4 '((a a a b b b b a a a a a b b a a a) + (a a b b b b a a + (a a)(b b)) + (a a a b (b a) b a b a)))) + '((*a ?b *b ?b a *a a *b *a) + (*a *b *b *a (*a) (*b)) + (? ? * (b a) * ? ?)))) + +(define (investigate units pats) + (do ((units units (cdr units))) + ((null? units)) + (do ((pats pats (cdr pats))) + ((null? pats)) + (do ((p (get (car units) 'pattern) + (cdr p))) + ((null? p)) + (match (car pats) (car p) '()))))) + +(time (browse)) +) + diff --git a/collects/tests/mzscheme/benchmarks/common/conform.sch b/collects/tests/mzscheme/benchmarks/common/conform.sch new file mode 100644 index 0000000000..bb088270c5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/conform.sch @@ -0,0 +1,619 @@ +; +; conform.scm [portable/R^399RS version] +; By Jim Miller [mods by oz] +; [call to run-benchmark added by wdc 14 Feb 1997] + +; (declare (usual-integrations)) + +;; SORT + +(define (vector-copy v) + (let* ((length (vector-length v)) + (result (make-vector length))) + (let loop ((n 0)) + (vector-set! result n (vector-ref v n)) + (if (= n length) + v + (loop (+ n 1)))))) + +(define (sort obj pred) + (define (loop l) + (if (and (pair? l) (pair? (cdr l))) + (split l '() '()) + l)) + + (define (split l one two) + (if (pair? l) + (split (cdr l) two (cons (car l) one)) + (merge (loop one) (loop two)))) + + (define (merge one two) + (cond ((null? one) two) + ((pred (car two) (car one)) + (cons (car two) + (merge (cdr two) one))) + (else + (cons (car one) + (merge (cdr one) two))))) + + (cond ((or (pair? obj) (null? obj)) + (loop obj)) + ((vector? obj) + (sort! (vector-copy obj) pred)) + (else + (error "sort: argument should be a list or vector" obj)))) + +;; This merge sort is stable for partial orders (for predicates like +;; <=, rather than like <). + +(define (sort! v pred) + (define (sort-internal! vec temp low high) + (if (< low high) + (let* ((middle (quotient (+ low high) 2)) + (next (+ middle 1))) + (sort-internal! temp vec low middle) + (sort-internal! temp vec next high) + (let loop ((p low) (p1 low) (p2 next)) + (if (not (> p high)) + (cond ((> p1 middle) + (vector-set! vec p (vector-ref temp p2)) + (loop (+ p 1) p1 (+ p2 1))) + ((or (> p2 high) + (pred (vector-ref temp p1) + (vector-ref temp p2))) + (vector-set! vec p (vector-ref temp p1)) + (loop (+ p 1) (+ p1 1) p2)) + (else + (vector-set! vec p (vector-ref temp p2)) + (loop (+ p 1) p1 (+ p2 1))))))))) + + (if (not (vector? v)) + (error "sort!: argument not a vector" v)) + + (sort-internal! v + (vector-copy v) + 0 + (- (vector-length v) 1)) + v) + +;; SET OPERATIONS +; (representation as lists with distinct elements) + +(define (adjoin element set) + (if (memq element set) set (cons element set))) + +(define (eliminate element set) + (cond ((null? set) set) + ((eq? element (car set)) (cdr set)) + (else (cons (car set) (eliminate element (cdr set)))))) + +(define (intersect list1 list2) + (let loop ((l list1)) + (cond ((null? l) '()) + ((memq (car l) list2) (cons (car l) (loop (cdr l)))) + (else (loop (cdr l)))))) + +(define (union list1 list2) + (if (null? list1) + list2 + (union (cdr list1) + (adjoin (car list1) list2)))) + +;; GRAPH NODES + +; (define-structure +; (internal-node +; (print-procedure (unparser/standard-method +; 'graph-node +; (lambda (state node) +; (unparse-object state (internal-node-name node)))))) +; name +; (green-edges '()) +; (red-edges '()) +; blue-edges) + +; Above is MIT version; below is portable + +(define make-internal-node vector) +(define (internal-node-name node) (vector-ref node 0)) +(define (internal-node-green-edges node) (vector-ref node 1)) +(define (internal-node-red-edges node) (vector-ref node 2)) +(define (internal-node-blue-edges node) (vector-ref node 3)) +(define (set-internal-node-name! node name) (vector-set! node 0 name)) +(define (set-internal-node-green-edges! node edges) (vector-set! node 1 edges)) +(define (set-internal-node-red-edges! node edges) (vector-set! node 2 edges)) +(define (set-internal-node-blue-edges! node edges) (vector-set! node 3 edges)) + +; End of portability stuff + +(define (make-node name . blue-edges) ; User's constructor + (let ((name (if (symbol? name) (symbol->string name) name)) + (blue-edges (if (null? blue-edges) 'NOT-A-NODE-YET (car blue-edges)))) + (make-internal-node name '() '() blue-edges))) + +(define (copy-node node) + (make-internal-node (name node) '() '() (blue-edges node))) + +; Selectors + +(define name internal-node-name) +(define (make-edge-getter selector) + (lambda (node) + (if (or (none-node? node) (any-node? node)) + (error "Can't get edges from the ANY or NONE nodes") + (selector node)))) +(define red-edges (make-edge-getter internal-node-red-edges)) +(define green-edges (make-edge-getter internal-node-green-edges)) +(define blue-edges (make-edge-getter internal-node-blue-edges)) + +; Mutators + +(define (make-edge-setter mutator!) + (lambda (node value) + (cond ((any-node? node) (error "Can't set edges from the ANY node")) + ((none-node? node) 'OK) + (else (mutator! node value))))) +(define set-red-edges! (make-edge-setter set-internal-node-red-edges!)) +(define set-green-edges! (make-edge-setter set-internal-node-green-edges!)) +(define set-blue-edges! (make-edge-setter set-internal-node-blue-edges!)) + +;; BLUE EDGES + +; (define-structure +; (blue-edge +; (print-procedure +; (unparser/standard-method +; 'blue-edge +; (lambda (state edge) +; (unparse-object state (blue-edge-operation edge)))))) +; operation arg-node res-node) + +; Above is MIT version; below is portable + +(define make-blue-edge vector) +(define (blue-edge-operation edge) (vector-ref edge 0)) +(define (blue-edge-arg-node edge) (vector-ref edge 1)) +(define (blue-edge-res-node edge) (vector-ref edge 2)) +(define (set-blue-edge-operation! edge value) (vector-set! edge 0 value)) +(define (set-blue-edge-arg-node! edge value) (vector-set! edge 1 value)) +(define (set-blue-edge-res-node! edge value) (vector-set! edge 2 value)) + +; End of portability stuff + +; Selectors +(define operation blue-edge-operation) +(define arg-node blue-edge-arg-node) +(define res-node blue-edge-res-node) + +; Mutators +(define set-arg-node! set-blue-edge-arg-node!) +(define set-res-node! set-blue-edge-res-node!) + +; Higher level operations on blue edges + +(define (lookup-op op node) + (let loop ((edges (blue-edges node))) + (cond ((null? edges) '()) + ((eq? op (operation (car edges))) (car edges)) + (else (loop (cdr edges)))))) + +(define (has-op? op node) + (not (null? (lookup-op op node)))) + +; Add a (new) blue edge to a node + +; (define (adjoin-blue-edge! blue-edge node) +; (let ((current-one (lookup-op (operation blue-edge) node))) +; (cond ((null? current-one) +; (set-blue-edges! node +; (cons blue-edge (blue-edges node)))) +; ((and (eq? (arg-node current-one) (arg-node blue-edge)) +; (eq? (res-node current-one) (res-node blue-edge))) +; 'OK) +; (else (error "Two non-equivalent blue edges for op" +; blue-edge node))))) + +;; GRAPHS + +; (define-structure +; (internal-graph +; (print-procedure +; (unparser/standard-method 'graph +; (lambda (state edge) +; (unparse-object state (map name (internal-graph-nodes edge))))))) +; nodes already-met already-joined) + +; Above is MIT version; below is portable + +(define make-internal-graph vector) +(define (internal-graph-nodes graph) (vector-ref graph 0)) +(define (internal-graph-already-met graph) (vector-ref graph 1)) +(define (internal-graph-already-joined graph) (vector-ref graph 2)) +(define (set-internal-graph-nodes! graph nodes) (vector-set! graph 0 nodes)) + +; End of portability stuff + +; Constructor + +(define (make-graph . nodes) + (make-internal-graph nodes (make-empty-table) (make-empty-table))) + +; Selectors + +(define graph-nodes internal-graph-nodes) +(define already-met internal-graph-already-met) +(define already-joined internal-graph-already-joined) + +; Higher level functions on graphs + +(define (add-graph-nodes! graph nodes) + (set-internal-graph-nodes! graph (cons nodes (graph-nodes graph)))) + +(define (copy-graph g) + (define (copy-list l) (vector->list (list->vector l))) + (make-internal-graph + (copy-list (graph-nodes g)) + (already-met g) + (already-joined g))) + +(define (clean-graph g) + (define (clean-node node) + (if (not (or (any-node? node) (none-node? node))) + (begin + (set-green-edges! node '()) + (set-red-edges! node '())))) + (for-each clean-node (graph-nodes g)) + g) + +(define (canonicalize-graph graph classes) + (define (fix node) + (define (fix-set object selector mutator) + (mutator object + (map (lambda (node) + (find-canonical-representative node classes)) + (selector object)))) + (if (not (or (none-node? node) (any-node? node))) + (begin + (fix-set node green-edges set-green-edges!) + (fix-set node red-edges set-red-edges!) + (for-each + (lambda (blue-edge) + (set-arg-node! blue-edge + (find-canonical-representative (arg-node blue-edge) classes)) + (set-res-node! blue-edge + (find-canonical-representative (res-node blue-edge) classes))) + (blue-edges node)))) + node) + (define (fix-table table) + (define (canonical? node) (eq? node (find-canonical-representative node classes))) + (define (filter-and-fix predicate-fn update-fn list) + (let loop ((list list)) + (cond ((null? list) '()) + ((predicate-fn (car list)) + (cons (update-fn (car list)) (loop (cdr list)))) + (else (loop (cdr list)))))) + (define (fix-line line) + (filter-and-fix + (lambda (entry) (canonical? (car entry))) + (lambda (entry) (cons (car entry) + (find-canonical-representative (cdr entry) classes))) + line)) + (if (null? table) + '() + (cons (car table) + (filter-and-fix + (lambda (entry) (canonical? (car entry))) + (lambda (entry) (cons (car entry) (fix-line (cdr entry)))) + (cdr table))))) + (make-internal-graph + (map (lambda (class) (fix (car class))) classes) + (fix-table (already-met graph)) + (fix-table (already-joined graph)))) + +;; USEFUL NODES + +(define none-node (make-node 'none #t)) +(define (none-node? node) (eq? node none-node)) + +(define any-node (make-node 'any '())) +(define (any-node? node) (eq? node any-node)) + +;; COLORED EDGE TESTS + + +(define (green-edge? from-node to-node) + (cond ((any-node? from-node) #f) + ((none-node? from-node) #t) + ((memq to-node (green-edges from-node)) #t) + (else #f))) + +(define (red-edge? from-node to-node) + (cond ((any-node? from-node) #f) + ((none-node? from-node) #t) + ((memq to-node (red-edges from-node)) #t) + (else #f))) + +;; SIGNATURE + +; Return signature (i.e. ) given an operation and a node + +(define sig + (let ((none-comma-any (cons none-node any-node))) + (lambda (op node) ; Returns (arg, res) + (let ((the-edge (lookup-op op node))) + (if (not (null? the-edge)) + (cons (arg-node the-edge) (res-node the-edge)) + none-comma-any))))) + +; Selectors from signature + +(define (arg pair) (car pair)) +(define (res pair) (cdr pair)) + +;; CONFORMITY + +(define (conforms? t1 t2) + (define nodes-with-red-edges-out '()) + (define (add-red-edge! from-node to-node) + (set-red-edges! from-node (adjoin to-node (red-edges from-node))) + (set! nodes-with-red-edges-out + (adjoin from-node nodes-with-red-edges-out))) + (define (greenify-red-edges! from-node) + (set-green-edges! from-node + (append (red-edges from-node) (green-edges from-node))) + (set-red-edges! from-node '())) + (define (delete-red-edges! from-node) + (set-red-edges! from-node '())) + (define (does-conform t1 t2) + (cond ((or (none-node? t1) (any-node? t2)) #t) + ((or (any-node? t1) (none-node? t2)) #f) + ((green-edge? t1 t2) #t) + ((red-edge? t1 t2) #t) + (else + (add-red-edge! t1 t2) + (let loop ((blues (blue-edges t2))) + (if (null? blues) + #t + (let* ((current-edge (car blues)) + (phi (operation current-edge))) + (and (has-op? phi t1) + (does-conform + (res (sig phi t1)) + (res (sig phi t2))) + (does-conform + (arg (sig phi t2)) + (arg (sig phi t1))) + (loop (cdr blues))))))))) + (let ((result (does-conform t1 t2))) + (for-each (if result greenify-red-edges! delete-red-edges!) + nodes-with-red-edges-out) + result)) + +(define (equivalent? a b) + (and (conforms? a b) (conforms? b a))) + +;; EQUIVALENCE CLASSIFICATION +; Given a list of nodes, return a list of equivalence classes + +(define (classify nodes) + (let node-loop ((classes '()) + (nodes nodes)) + (if (null? nodes) + (map (lambda (class) + (sort class + (lambda (node1 node2) + (< (string-length (name node1)) + (string-length (name node2)))))) + classes) + (let ((this-node (car nodes))) + (define (add-node classes) + (cond ((null? classes) (list (list this-node))) + ((equivalent? this-node (caar classes)) + (cons (cons this-node (car classes)) + (cdr classes))) + (else (cons (car classes) + (add-node (cdr classes)))))) + (node-loop (add-node classes) + (cdr nodes)))))) + +; Given a node N and a classified set of nodes, +; find the canonical member corresponding to N + +(define (find-canonical-representative element classification) + (let loop ((classes classification)) + (cond ((null? classes) (error "Can't classify" element)) + ((memq element (car classes)) (car (car classes))) + (else (loop (cdr classes)))))) + +; Reduce a graph by taking only one member of each equivalence +; class and canonicalizing all outbound pointers + +(define (reduce graph) + (let ((classes (classify (graph-nodes graph)))) + (canonicalize-graph graph classes))) + +;; TWO DIMENSIONAL TABLES + +(define (make-empty-table) (list 'TABLE)) + +(define (lookup table x y) + (let ((one (assq x (cdr table)))) + (if one + (let ((two (assq y (cdr one)))) + (if two (cdr two) #f)) + #f))) + +(define (insert! table x y value) + (define (make-singleton-table x y) + (list (cons x y))) + (let ((one (assq x (cdr table)))) + (if one + (set-cdr! one (cons (cons y value) (cdr one))) + (set-cdr! table (cons (cons x (make-singleton-table y value)) + (cdr table)))))) + +;; MEET/JOIN +; These update the graph when computing the node for node1*node2 + +(define (blue-edge-operate arg-fn res-fn graph op sig1 sig2) + (make-blue-edge op + (arg-fn graph (arg sig1) (arg sig2)) + (res-fn graph (res sig1) (res sig2)))) + +(define (meet graph node1 node2) + (cond ((eq? node1 node2) node1) + ((or (any-node? node1) (any-node? node2)) any-node) ; canonicalize + ((none-node? node1) node2) + ((none-node? node2) node1) + ((lookup (already-met graph) node1 node2)) ; return it if found + ((conforms? node1 node2) node2) + ((conforms? node2 node1) node1) + (else + (let ((result + (make-node (string-append "(" (name node1) " ^ " (name node2) ")")))) + (add-graph-nodes! graph result) + (insert! (already-met graph) node1 node2 result) + (set-blue-edges! result + (map + (lambda (op) + (blue-edge-operate join meet graph op (sig op node1) (sig op node2))) + (intersect (map operation (blue-edges node1)) + (map operation (blue-edges node2))))) + result)))) + +(define (join graph node1 node2) + (cond ((eq? node1 node2) node1) + ((any-node? node1) node2) + ((any-node? node2) node1) + ((or (none-node? node1) (none-node? node2)) none-node) ; canonicalize + ((lookup (already-joined graph) node1 node2)) ; return it if found + ((conforms? node1 node2) node1) + ((conforms? node2 node1) node2) + (else + (let ((result + (make-node (string-append "(" (name node1) " v " (name node2) ")")))) + (add-graph-nodes! graph result) + (insert! (already-joined graph) node1 node2 result) + (set-blue-edges! result + (map + (lambda (op) + (blue-edge-operate meet join graph op (sig op node1) (sig op node2))) + (union (map operation (blue-edges node1)) + (map operation (blue-edges node2))))) + result)))) + +;; MAKE A LATTICE FROM A GRAPH + +(define (make-lattice g print?) + (define (step g) + (let* ((copy (copy-graph g)) + (nodes (graph-nodes copy))) + (for-each (lambda (first) + (for-each (lambda (second) + (meet copy first second) + (join copy first second)) + nodes)) + nodes) + copy)) + (define (loop g count) + (if print? (display count)) + (let ((lattice (step g))) + (if print? (begin (display " -> ") + (display (length (graph-nodes lattice))))) + (let* ((new-g (reduce lattice)) + (new-count (length (graph-nodes new-g)))) + (if (= new-count count) + (begin + (if print? (newline)) + new-g) + (begin + (if print? (begin (display " -> ") + (display new-count) (newline))) + (loop new-g new-count)))))) + (let ((graph + (apply make-graph + (adjoin any-node (adjoin none-node (graph-nodes (clean-graph g))))))) + (loop graph (length (graph-nodes graph))))) + +;; DEBUG and TEST + +(define a '()) +(define b '()) +(define c '()) +(define d '()) + +(define (reset) + (set! a (make-node 'a)) + (set! b (make-node 'b)) + (set-blue-edges! a (list (make-blue-edge 'phi any-node b))) + (set-blue-edges! b (list (make-blue-edge 'phi any-node a) + (make-blue-edge 'theta any-node b))) + (set! c (make-node "c")) + (set! d (make-node "d")) + (set-blue-edges! c (list (make-blue-edge 'theta any-node b))) + (set-blue-edges! d (list (make-blue-edge 'phi any-node c) + (make-blue-edge 'theta any-node d))) + '(made a b c d)) + +(define (test) + (reset) + (map name + (graph-nodes + (make-lattice (make-graph a b c d any-node none-node) #t)))) + ;;; note printflag #t +;(define (time-test) +; (let ((t (runtime))) +; (let ((ans (test))) +; (cons ans (- (runtime) t))))) + +; +; run and make sure result is correct +; +(define (go) + (reset) + (let ((result '("(((b v d) ^ a) v c)" + "(c ^ d)" + "(b v (a ^ d))" + "((a v d) ^ b)" + "(b v d)" + "(b ^ (a v c))" + "(a v (c ^ d))" + "((b v d) ^ a)" + "(c v (a v d))" + "(a v c)" + "(d v (b ^ (a v c)))" + "(d ^ (a v c))" + "((a ^ d) v c)" + "((a ^ b) v d)" + "(((a v d) ^ b) v (a ^ d))" + "(b ^ d)" + "(b v (a v d))" + "(a ^ c)" + "(b ^ (c v d))" + "(a ^ b)" + "(a v b)" + "((a ^ d) ^ b)" + "(a ^ d)" + "(a v d)" + "d" + "(c v d)" + "a" + "b" + "c" + "any" + "none"))) + + (if (equal? (test) result) + (display " ok.") + (display " um.")) + (newline))) + +;[mods made by wdc] +;(go) +;(exit) + +(define (conform-benchmark . rest) + (time (go))) + +(conform-benchmark) + diff --git a/collects/tests/mzscheme/benchmarks/common/conform.ss b/collects/tests/mzscheme/benchmarks/common/conform.ss new file mode 100644 index 0000000000..0e5b3cc2cd --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/conform.ss @@ -0,0 +1,2 @@ + +(module conform "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/cpstack.sch b/collects/tests/mzscheme/benchmarks/common/cpstack.sch new file mode 100644 index 0000000000..6ef109b859 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/cpstack.sch @@ -0,0 +1,34 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: cpstak.sch +; Description: continuation-passing version of TAK +; Author: Will Clinger +; Created: 20-Aug-87 +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; CPSTAK -- A continuation-passing version of the TAK benchmark. +;;; A good test of first class procedures and tail recursion. + +(define (cpstak x y z) + (define (tak x y z k) + (if (not (< y x)) + (k z) + (tak (- x 1) + y + z + (lambda (v1) + (tak (- y 1) + z + x + (lambda (v2) + (tak (- z 1) + x + y + (lambda (v3) + (tak v1 v2 v3 k))))))))) + (tak x y z (lambda (a) a))) + +;;; call: (cpstak 18 12 6) + +(time (cpstak 18 12 2)) diff --git a/collects/tests/mzscheme/benchmarks/common/cpstack.ss b/collects/tests/mzscheme/benchmarks/common/cpstack.ss new file mode 100644 index 0000000000..c39bfd7276 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/cpstack.ss @@ -0,0 +1,2 @@ + +(module cpstack "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/ctak.sch b/collects/tests/mzscheme/benchmarks/common/ctak.sch new file mode 100644 index 0000000000..f7ccd91363 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/ctak.sch @@ -0,0 +1,55 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: ctak.sch +; Description: The ctak benchmark +; Author: Richard Gabriel +; Created: 5-Apr-85 +; Modified: 10-Apr-85 14:53:02 (Bob Shaw) +; 24-Jul-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; The original version of this benchmark used a continuation mechanism that +; is less powerful than call-with-current-continuation and also relied on +; dynamic binding, which is not provided in standard Scheme. Since the +; intent of the benchmark seemed to be to test non-local exits, the dynamic +; binding has been replaced here by lexical binding. + +; For Scheme the comment that follows should read: +;;; CTAK -- A version of the TAK procedure that uses continuations. + +;;; CTAK -- A version of the TAK function that uses the CATCH/THROW facility. + +(define (ctak x y z) + (call-with-current-continuation + (lambda (k) + (ctak-aux k x y z)))) + +(define (ctak-aux k x y z) + (cond ((not (< y x)) ;xy + (k z)) + (else (call-with-current-continuation + (ctak-aux + k + (call-with-current-continuation + (lambda (k) + (ctak-aux k + (- x 1) + y + z))) + (call-with-current-continuation + (lambda (k) + (ctak-aux k + (- y 1) + z + x))) + (call-with-current-continuation + (lambda (k) + (ctak-aux k + (- z 1) + x + y)))))))) + +;;; call: (ctak 18 12 6) + +(time (ctak 18 12 6)) diff --git a/collects/tests/mzscheme/benchmarks/common/ctak.ss b/collects/tests/mzscheme/benchmarks/common/ctak.ss new file mode 100644 index 0000000000..a5be89924f --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/ctak.ss @@ -0,0 +1,2 @@ + +(module ctak "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/dderiv.ss b/collects/tests/mzscheme/benchmarks/common/dderiv.ss new file mode 100644 index 0000000000..0710bdbba1 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/dderiv.ss @@ -0,0 +1,99 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: dderiv.sch +; Description: DDERIV benchmark from the Gabriel tests +; Author: Vaughan Pratt +; Created: 8-Apr-85 +; Modified: 10-Apr-85 14:53:29 (Bob Shaw) +; 23-Jul-87 (Will Clinger) +; 9-Feb-88 (Will Clinger) +; Language: Scheme (but see note below) +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Note: This benchmark uses property lists. The procedures that must +; be supplied are get and put, where (put x y z) is equivalent to Common +; Lisp's (setf (get x y) z). + +;;; DDERIV -- Symbolic derivative benchmark written by Vaughn Pratt. + +;;; This benchmark is a variant of the simple symbolic derivative program +;;; (DERIV). The main change is that it is `table-driven.' Instead of using a +;;; large COND that branches on the CAR of the expression, this program finds +;;; the code that will take the derivative on the property list of the atom in +;;; the CAR position. So, when the expression is (+ . ), the code +;;; stored under the atom '+ with indicator DERIV will take and +;;; return the derivative for '+. The way that MacLisp does this is with the +;;; special form: (DEFUN (FOO BAR) ...). This is exactly like DEFUN with an +;;; atomic name in that it expects an argument list and the compiler compiles +;;; code, but the name of the function with that code is stored on the +;;; property list of FOO under the indicator BAR, in this case. You may have +;;; to do something like: + +;;; :property keyword is not Common Lisp. + +; Returns the wrong answer for quotients. +; Fortunately these aren't used in the benchmark. + +(module dderiv mzscheme + +(define pg-alist '()) +(define (put sym d what) + (set! pg-alist (cons (cons sym what) pg-alist))) +(define (get sym d) + (cdr (assq sym pg-alist))) + +(define (dderiv-aux a) + (list '/ (dderiv a) a)) + +(define (+dderiv a) + (cons '+ (map dderiv a))) + +(put '+ 'dderiv +dderiv) ; install procedure on the property list + +(define (-dderiv a) + (cons '- (map dderiv a))) + +(put '- 'dderiv -dderiv) ; install procedure on the property list + +(define (*dderiv a) + (list '* (cons '* a) + (cons '+ (map dderiv-aux a)))) + +(put '* 'dderiv *dderiv) ; install procedure on the property list + +(define (/dderiv a) + (list '- + (list '/ + (dderiv (car a)) + (cadr a)) + (list '/ + (car a) + (list '* + (cadr a) + (cadr a) + (dderiv (cadr a)))))) + +(put '/ 'dderiv /dderiv) ; install procedure on the property list + +(define (dderiv a) + (cond + ((not (pair? a)) + (cond ((eq? a 'x) 1) (else 0))) + (else (let ((dderiv (get (car a) 'dderiv))) + (cond (dderiv (dderiv (cdr a))) + (else 'error)))))) + +(define (run) + (do ((i 0 (+ i 1))) + ((= i 10000)) + (dderiv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (dderiv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (dderiv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (dderiv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (dderiv '(+ (* 3 x x) (* a x x) (* b x) 5)))) + +;;; call: (run) + +(time (run)) +) + diff --git a/collects/tests/mzscheme/benchmarks/common/deriv.sch b/collects/tests/mzscheme/benchmarks/common/deriv.sch new file mode 100644 index 0000000000..5b6e687db9 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/deriv.sch @@ -0,0 +1,59 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: deriv.sch +; Description: The DERIV benchmark from the Gabriel tests. +; Author: Vaughan Pratt +; Created: 8-Apr-85 +; Modified: 10-Apr-85 14:53:50 (Bob Shaw) +; 23-Jul-87 (Will Clinger) +; 9-Feb-88 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; DERIV -- Symbolic derivative benchmark written by Vaughn Pratt. +;;; It uses a simple subset of Lisp and does a lot of CONSing. + +; Returns the wrong answer for quotients. +; Fortunately these aren't used in the benchmark. + +(define (deriv-aux a) (list '/ (deriv a) a)) + +(define (deriv a) + (cond + ((not (pair? a)) + (cond ((eq? a 'x) 1) (else 0))) + ((eq? (car a) '+) + (cons '+ (map deriv (cdr a)))) + ((eq? (car a) '-) + (cons '- (map deriv + (cdr a)))) + ((eq? (car a) '*) + (list '* + a + (cons '+ (map deriv-aux (cdr a))))) + ((eq? (car a) '/) + (list '- + (list '/ + (deriv (cadr a)) + (caddr a)) + (list '/ + (cadr a) + (list '* + (caddr a) + (caddr a) + (deriv (caddr a)))))) + (else 'error))) + +(define (run) + (do ((i 0 (+ i 1))) + ((= i 10000)) + (deriv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (deriv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (deriv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (deriv '(+ (* 3 x x) (* a x x) (* b x) 5)) + (deriv '(+ (* 3 x x) (* a x x) (* b x) 5)))) + +;;; call: (run) + +(time (run)) + diff --git a/collects/tests/mzscheme/benchmarks/common/deriv.ss b/collects/tests/mzscheme/benchmarks/common/deriv.ss new file mode 100644 index 0000000000..31d2bcb067 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/deriv.ss @@ -0,0 +1,2 @@ + +(module deriv "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/destruct.sch b/collects/tests/mzscheme/benchmarks/common/destruct.sch new file mode 100644 index 0000000000..d401409cc3 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/destruct.sch @@ -0,0 +1,64 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: destruct.sch +; Description: DESTRUCTIVE benchmark from Gabriel tests +; Author: Bob Shaw, HPLabs/ATC +; Created: 8-Apr-85 +; Modified: 10-Apr-85 14:54:12 (Bob Shaw) +; 23-Jul-87 (Will Clinger) +; 22-Jan-88 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; append! is no longer a standard Scheme procedure, so it must be defined +; for implementations that don't already have it. + +(define (my-append! x y) + (if (null? x) + y + (do ((a x b) + (b (cdr x) (cdr b))) + ((null? b) + (set-cdr! a y) + x)))) + +;;; DESTRU -- Destructive operation benchmark + +(define (destructive n m) + (let ((l (do ((i 10 (- i 1)) + (a '() (cons '() a))) + ((= i 0) a)))) + (do ((i n (- i 1))) + ((= i 0)) + (cond ((null? (car l)) + (do ((l l (cdr l))) + ((null? l)) + (or (car l) + (set-car! l (cons '() '()))) + (my-append! (car l) + (do ((j m (- j 1)) + (a '() (cons '() a))) + ((= j 0) a))))) + (else + (do ((l1 l (cdr l1)) + (l2 (cdr l) (cdr l2))) + ((null? l2)) + (set-cdr! (do ((j (quotient (length (car l2)) 2) (- j 1)) + (a (car l2) (cdr a))) + ((zero? j) a) + (set-car! a i)) + (let ((n (quotient (length (car l1)) 2))) + (cond ((= n 0) (set-car! l1 '()) + (car l1)) + (else + (do ((j n (- j 1)) + (a (car l1) (cdr a))) + ((= j 1) + (let ((x (cdr a))) + (set-cdr! a '()) + x)) + (set-car! a i)))))))))))) + +;;; call: (destructive 600 50) + +(time (destructive 600 500)) diff --git a/collects/tests/mzscheme/benchmarks/common/destruct.ss b/collects/tests/mzscheme/benchmarks/common/destruct.ss new file mode 100644 index 0000000000..c53eb9b7fb --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/destruct.ss @@ -0,0 +1,2 @@ + +(module destruct "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/div.ss b/collects/tests/mzscheme/benchmarks/common/div.ss new file mode 100644 index 0000000000..753fa0bcd5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/div.ss @@ -0,0 +1,54 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: div.sch +; Description: DIV benchmarks +; Author: Richard Gabriel +; Created: 8-Apr-85 +; Modified: 19-Jul-85 18:28:01 (Bob Shaw) +; 23-Jul-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; DIV2 -- Benchmark which divides by 2 using lists of n ()'s. +;;; This file contains a recursive as well as an iterative test. + +(module div mzscheme +(define (create-n n) + (do ((n n (- n 1)) + (a '() (cons '() a))) + ((= n 0) a))) + +(define *ll* (create-n 200)) + +(define (iterative-div2 l) + (do ((l l (cddr l)) + (a '() (cons (car l) a))) + ((null? l) a))) + +(define (recursive-div2 l) + (cond ((null? l) '()) + (else (cons (car l) (recursive-div2 (cddr l)))))) + +(define (test-1 l) + (do ((i 3000 (- i 1))) + ((= i 0)) + (iterative-div2 l) + (iterative-div2 l) + (iterative-div2 l) + (iterative-div2 l))) + +(define (test-2 l) + (do ((i 3000 (- i 1))) + ((= i 0)) + (recursive-div2 l) + (recursive-div2 l) + (recursive-div2 l) + (recursive-div2 l))) + +;;; for the iterative test call: (test-1 *ll*) +;;; for the recursive test call: (test-2 *ll*) + +(time (test-1 *ll*)) +(time (test-2 *ll*)) +) + diff --git a/collects/tests/mzscheme/benchmarks/common/dynamic-input.txt.gz b/collects/tests/mzscheme/benchmarks/common/dynamic-input.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..44c16a1bdbf7703e1506067d2e8f4476e4ea1112 GIT binary patch literal 209619 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
6BWWui)eYv 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

7mN3IVhQIb7#!Q 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 GuKgDpN Binding +;; binding-key: Binding -> Key +;; binding-value: Binding -> Value +;; binding-show: Binding -> Symbol* +;; extend-env-with-binding: Env x Binding -> Env +;; extend-env-with-env: Env x Env -> Env +;; lookup: Key x Env -> (Binding + False) +;; env->list: Env -> Binding* +;; env-show: Env -> Symbol* + + +; bindings + +(define gen-binding cons) +; generates a type binding, binding a symbol to a type variable + +(define binding-key car) +; returns the key of a type binding + +(define binding-value cdr) +; returns the tvariable of a type binding + +(define (key-show key) + ; default show procedure for keys + key) + +(define (value-show value) + ; default show procedure for values + value) + +(define (binding-show binding) + ; returns a printable representation of a type binding + (cons (key-show (binding-key binding)) + (cons ': (value-show (binding-value binding))))) + + +; environments + +(define dynamic-empty-env '()) +; returns the empty environment + +(define (extend-env-with-binding env binding) + ; extends env with a binding, which hides any other binding in env + ; for the same key (see dynamic-lookup) + ; returns the extended environment + (cons binding env)) + +(define (extend-env-with-env env ext-env) + ; extends environment env with environment ext-env + ; a binding for a key in ext-env hides any binding in env for + ; the same key (see dynamic-lookup) + ; returns the extended environment + (append ext-env env)) + +(define dynamic-lookup (lambda (x l) (assv x l))) +; returns the first pair in env that matches the key; returns #f +; if no such pair exists + +(define (env->list e) + ; converts an environment to a list of bindings + e) + +(define (env-show env) + ; returns a printable list representation of a type environment + (map binding-show env)) +;---------------------------------------------------------------------------- +; Parsing for Scheme +;---------------------------------------------------------------------------- + + +;; Needed packages: environment management + +;(load "env-mgmt.ss") +;(load "pars-act.ss") + +;; Lexical notions + +(define syntactic-keywords + ;; source: IEEE Scheme, 7.1, , + '(lambda if set! begin cond and or case let let* letrec do + quasiquote else => define unquote unquote-splicing)) + + +;; Parse routines + +; Datum + +; dynamic-parse-datum: parses nonterminal + +(define (dynamic-parse-datum e) + ;; Source: IEEE Scheme, sect. 7.2, + ;; Note: "'" is parsed as 'quote, "`" as 'quasiquote, "," as + ;; 'unquote, ",@" as 'unquote-splicing (see sect. 4.2.5, p. 18) + ;; ***Note***: quasi-quotations are not permitted! (It would be + ;; necessary to pass the environment to dynamic-parse-datum.) + (cond + ((null? e) + (dynamic-parse-action-null-const)) + ((boolean? e) + (dynamic-parse-action-boolean-const e)) + ((char? e) + (dynamic-parse-action-char-const e)) + ((number? e) + (dynamic-parse-action-number-const e)) + ((string? e) + (dynamic-parse-action-string-const e)) + ((symbol? e) + (dynamic-parse-action-symbol-const e)) + ((vector? e) + (dynamic-parse-action-vector-const (map dynamic-parse-datum (vector->list e)))) + ((pair? e) + (dynamic-parse-action-pair-const (dynamic-parse-datum (car e)) + (dynamic-parse-datum (cdr e)))) + (else (error 'dynamic-parse-datum "Unknown datum: ~s" e)))) + + +; VarDef + +; dynamic-parse-formal: parses nonterminal in defining occurrence position + +(define (dynamic-parse-formal f-env e) + ; e is an arbitrary object, f-env is a forbidden environment; + ; returns: a variable definition (a binding for the symbol), plus + ; the value of the binding as a result + (if (symbol? e) + (cond + ((memq e syntactic-keywords) + (error 'dynamic-parse-formal "Illegal identifier (keyword): ~s" e)) + ((dynamic-lookup e f-env) + (error 'dynamic-parse-formal "Duplicate variable definition: ~s" e)) + (else (let ((dynamic-parse-action-result (dynamic-parse-action-var-def e))) + (cons (gen-binding e dynamic-parse-action-result) + dynamic-parse-action-result)))) + (error 'dynamic-parse-formal "Not an identifier: ~s" e))) + +; dynamic-parse-formal* + +(define (dynamic-parse-formal* formals) + ;; parses a list of formals and returns a pair consisting of generated + ;; environment and list of parsing action results + (letrec + ((pf* + (lambda (f-env results formals) + ;; f-env: "forbidden" environment (to avoid duplicate defs) + ;; results: the results of the parsing actions + ;; formals: the unprocessed formals + ;; Note: generates the results of formals in reverse order! + (cond + ((null? formals) + (cons f-env results)) + ((pair? formals) + (let* ((fst-formal (car formals)) + (binding-result (dynamic-parse-formal f-env fst-formal)) + (binding (car binding-result)) + (var-result (cdr binding-result))) + (pf* + (extend-env-with-binding f-env binding) + (cons var-result results) + (cdr formals)))) + (else (error 'dynamic-parse-formal* "Illegal formals: ~s" formals)))))) + (let ((renv-rres (pf* dynamic-empty-env '() formals))) + (cons (car renv-rres) (reverse (cdr renv-rres)))))) + + +; dynamic-parse-formals: parses + +(define (dynamic-parse-formals formals) + ;; parses ; see IEEE Scheme, sect. 7.3 + ;; returns a pair: env and result + (letrec ((pfs (lambda (f-env formals) + (cond + ((null? formals) + (cons dynamic-empty-env (dynamic-parse-action-null-formal))) + ((pair? formals) + (let* ((fst-formal (car formals)) + (rem-formals (cdr formals)) + (bind-res (dynamic-parse-formal f-env fst-formal)) + (bind (car bind-res)) + (res (cdr bind-res)) + (nf-env (extend-env-with-binding f-env bind)) + (renv-res* (pfs nf-env rem-formals)) + (renv (car renv-res*)) + (res* (cdr renv-res*))) + (cons + (extend-env-with-binding renv bind) + (dynamic-parse-action-pair-formal res res*)))) + (else + (let* ((bind-res (dynamic-parse-formal f-env formals)) + (bind (car bind-res)) + (res (cdr bind-res))) + (cons + (extend-env-with-binding dynamic-empty-env bind) + res))))))) + (pfs dynamic-empty-env formals))) + + +; Expr + +; dynamic-parse-expression: parses nonterminal + +(define (dynamic-parse-expression env e) + (cond + ((symbol? e) + (dynamic-parse-variable env e)) + ((pair? e) + (let ((op (car e)) (args (cdr e))) + (case op + ((quote) (dynamic-parse-quote env args)) + ((lambda) (dynamic-parse-lambda env args)) + ((if) (dynamic-parse-if env args)) + ((set!) (dynamic-parse-set env args)) + ((begin) (dynamic-parse-begin env args)) + ((cond) (dynamic-parse-cond env args)) + ((case) (dynamic-parse-case env args)) + ((and) (dynamic-parse-and env args)) + ((or) (dynamic-parse-or env args)) + ((let) (dynamic-parse-let env args)) + ((let*) (dynamic-parse-let* env args)) + ((letrec) (dynamic-parse-letrec env args)) + ((do) (dynamic-parse-do env args)) + ((quasiquote) (dynamic-parse-quasiquote env args)) + (else (dynamic-parse-procedure-call env op args))))) + (else (dynamic-parse-datum e)))) + +; dynamic-parse-expression* + +(define (dynamic-parse-expression* env exprs) + ;; Parses lists of expressions (returns them in the right order!) + (letrec ((pe* + (lambda (results es) + (cond + ((null? es) results) + ((pair? es) (pe* (cons (dynamic-parse-expression env (car es)) results) (cdr es))) + (else (error 'dynamic-parse-expression* "Not a list of expressions: ~s" es)))))) + (reverse (pe* '() exprs)))) + + +; dynamic-parse-expressions + +(define (dynamic-parse-expressions env exprs) + ;; parses lists of arguments of a procedure call + (cond + ((null? exprs) (dynamic-parse-action-null-arg)) + ((pair? exprs) (let* ((fst-expr (car exprs)) + (rem-exprs (cdr exprs)) + (fst-res (dynamic-parse-expression env fst-expr)) + (rem-res (dynamic-parse-expressions env rem-exprs))) + (dynamic-parse-action-pair-arg fst-res rem-res))) + (else (error 'dynamic-parse-expressions "Illegal expression list: ~s" + exprs)))) + + +; dynamic-parse-variable: parses variables (applied occurrences) + +(define (dynamic-parse-variable env e) + (if (symbol? e) + (if (memq e syntactic-keywords) + (error 'dynamic-parse-variable "Illegal identifier (keyword): ~s" e) + (let ((assoc-var-def (dynamic-lookup e env))) + (if assoc-var-def + (dynamic-parse-action-variable (binding-value assoc-var-def)) + (dynamic-parse-action-identifier e)))) + (error 'dynamic-parse-variable "Not an identifier: ~s" e))) + + +; dynamic-parse-procedure-call + +(define (dynamic-parse-procedure-call env op args) + (dynamic-parse-action-procedure-call + (dynamic-parse-expression env op) + (dynamic-parse-expressions env args))) + + +; dynamic-parse-quote + +(define (dynamic-parse-quote env args) + (if (list-of-1? args) + (dynamic-parse-datum (car args)) + (error 'dynamic-parse-quote "Not a datum (multiple arguments): ~s" args))) + + +; dynamic-parse-lambda + +(define (dynamic-parse-lambda env args) + (if (pair? args) + (let* ((formals (car args)) + (body (cdr args)) + (nenv-fresults (dynamic-parse-formals formals)) + (nenv (car nenv-fresults)) + (fresults (cdr nenv-fresults))) + (dynamic-parse-action-lambda-expression + fresults + (dynamic-parse-body (extend-env-with-env env nenv) body))) + (error 'dynamic-parse-lambda "Illegal formals/body: ~s" args))) + + +; dynamic-parse-body + +(define (dynamic-parse-body env body) + ; = * + + (define (def-var* f-env body) + ; finds the defined variables in a body and returns an + ; environment containing them + (if (pair? body) + (let ((n-env (def-var f-env (car body)))) + (if n-env + (def-var* n-env (cdr body)) + f-env)) + f-env)) + (define (def-var f-env clause) + ; finds the defined variables in a single clause and extends + ; f-env accordingly; returns false if it's not a definition + (if (pair? clause) + (case (car clause) + ((define) (if (pair? (cdr clause)) + (let ((pattern (cadr clause))) + (cond + ((symbol? pattern) + (extend-env-with-binding + f-env + (gen-binding pattern + (dynamic-parse-action-var-def pattern)))) + ((and (pair? pattern) (symbol? (car pattern))) + (extend-env-with-binding + f-env + (gen-binding (car pattern) + (dynamic-parse-action-var-def + (car pattern))))) + (else f-env))) + f-env)) + ((begin) (def-var* f-env (cdr clause))) + (else #f)) + #f)) + (if (pair? body) + (dynamic-parse-command* (def-var* env body) body) + (error 'dynamic-parse-body "Illegal body: ~s" body))) + +; dynamic-parse-if + +(define (dynamic-parse-if env args) + (cond + ((list-of-3? args) + (dynamic-parse-action-conditional + (dynamic-parse-expression env (car args)) + (dynamic-parse-expression env (cadr args)) + (dynamic-parse-expression env (caddr args)))) + ((list-of-2? args) + (dynamic-parse-action-conditional + (dynamic-parse-expression env (car args)) + (dynamic-parse-expression env (cadr args)) + (dynamic-parse-action-empty))) + (else (error 'dynamic-parse-if "Not an if-expression: ~s" args)))) + + +; dynamic-parse-set + +(define (dynamic-parse-set env args) + (if (list-of-2? args) + (dynamic-parse-action-assignment + (dynamic-parse-variable env (car args)) + (dynamic-parse-expression env (cadr args))) + (error 'dynamic-parse-set "Not a variable/expression pair: ~s" args))) + + +; dynamic-parse-begin + +(define (dynamic-parse-begin env args) + (dynamic-parse-action-begin-expression + (dynamic-parse-body env args))) + + +; dynamic-parse-cond + +(define (dynamic-parse-cond env args) + (if (and (pair? args) (list? args)) + (dynamic-parse-action-cond-expression + (map (lambda (e) + (dynamic-parse-cond-clause env e)) + args)) + (error 'dynamic-parse-cond "Not a list of cond-clauses: ~s" args))) + +; dynamic-parse-cond-clause + +(define (dynamic-parse-cond-clause env e) + ;; ***Note***: Only ( ) is permitted! + (if (pair? e) + (cons + (if (eqv? (car e) 'else) + (dynamic-parse-action-empty) + (dynamic-parse-expression env (car e))) + (dynamic-parse-body env (cdr e))) + (error 'dynamic-parse-cond-clause "Not a cond-clause: ~s" e))) + + +; dynamic-parse-and + +(define (dynamic-parse-and env args) + (if (list? args) + (dynamic-parse-action-and-expression + (dynamic-parse-expression* env args)) + (error 'dynamic-parse-and "Not a list of arguments: ~s" args))) + + +; dynamic-parse-or + +(define (dynamic-parse-or env args) + (if (list? args) + (dynamic-parse-action-or-expression + (dynamic-parse-expression* env args)) + (error 'dynamic-parse-or "Not a list of arguments: ~s" args))) + + +; dynamic-parse-case + +(define (dynamic-parse-case env args) + (if (and (list? args) (> (length args) 1)) + (dynamic-parse-action-case-expression + (dynamic-parse-expression env (car args)) + (map (lambda (e) + (dynamic-parse-case-clause env e)) + (cdr args))) + (error 'dynamic-parse-case "Not a list of clauses: ~s" args))) + +; dynamic-parse-case-clause + +(define (dynamic-parse-case-clause env e) + (if (pair? e) + (cons + (cond + ((eqv? (car e) 'else) + (list (dynamic-parse-action-empty))) + ((list? (car e)) + (map dynamic-parse-datum (car e))) + (else (error 'dynamic-parse-case-clause "Not a datum list: ~s" (car e)))) + (dynamic-parse-body env (cdr e))) + (error 'dynamic-parse-case-clause "Not case clause: ~s" e))) + + +; dynamic-parse-let + +(define (dynamic-parse-let env args) + (if (pair? args) + (if (symbol? (car args)) + (dynamic-parse-named-let env args) + (dynamic-parse-normal-let env args)) + (error 'dynamic-parse-let "Illegal bindings/body: ~s" args))) + + +; dynamic-parse-normal-let + +(define (dynamic-parse-normal-let env args) + ;; parses "normal" let-expressions + (let* ((bindings (car args)) + (body (cdr args)) + (env-ast (dynamic-parse-parallel-bindings env bindings)) + (nenv (car env-ast)) + (bresults (cdr env-ast))) + (dynamic-parse-action-let-expression + bresults + (dynamic-parse-body (extend-env-with-env env nenv) body)))) + +; dynamic-parse-named-let + +(define (dynamic-parse-named-let env args) + ;; parses a named let-expression + (if (pair? (cdr args)) + (let* ((variable (car args)) + (bindings (cadr args)) + (body (cddr args)) + (vbind-vres (dynamic-parse-formal dynamic-empty-env variable)) + (vbind (car vbind-vres)) + (vres (cdr vbind-vres)) + (env-ast (dynamic-parse-parallel-bindings env bindings)) + (nenv (car env-ast)) + (bresults (cdr env-ast))) + (dynamic-parse-action-named-let-expression + vres bresults + (dynamic-parse-body (extend-env-with-env + (extend-env-with-binding env vbind) + nenv) body))) + (error 'dynamic-parse-named-let "Illegal named let-expression: ~s" args))) + + +; dynamic-parse-parallel-bindings + +(define (dynamic-parse-parallel-bindings env bindings) + ; returns a pair consisting of an environment + ; and a list of pairs (variable . asg) + ; ***Note***: the list of pairs is returned in reverse unzipped form! + (if (list-of-list-of-2s? bindings) + (let* ((env-formals-asg + (dynamic-parse-formal* (map car bindings))) + (nenv (car env-formals-asg)) + (bresults (cdr env-formals-asg)) + (exprs-asg + (dynamic-parse-expression* env (map cadr bindings)))) + (cons nenv (cons bresults exprs-asg))) + (error 'dynamic-parse-parallel-bindings + "Not a list of bindings: ~s" bindings))) + + +; dynamic-parse-let* + +(define (dynamic-parse-let* env args) + (if (pair? args) + (let* ((bindings (car args)) + (body (cdr args)) + (env-ast (dynamic-parse-sequential-bindings env bindings)) + (nenv (car env-ast)) + (bresults (cdr env-ast))) + (dynamic-parse-action-let*-expression + bresults + (dynamic-parse-body (extend-env-with-env env nenv) body))) + (error 'dynamic-parse-let* "Illegal bindings/body: ~s" args))) + +; dynamic-parse-sequential-bindings + +(define (dynamic-parse-sequential-bindings env bindings) + ; returns a pair consisting of an environment + ; and a list of pairs (variable . asg) + ;; ***Note***: the list of pairs is returned in reverse unzipped form! + (letrec + ((psb + (lambda (f-env c-env var-defs expr-asgs binds) + ;; f-env: forbidden environment + ;; c-env: constructed environment + ;; var-defs: results of formals + ;; expr-asgs: results of corresponding expressions + ;; binds: reminding bindings to process + (cond + ((null? binds) + (cons f-env (cons var-defs expr-asgs))) + ((pair? binds) + (let ((fst-bind (car binds))) + (if (list-of-2? fst-bind) + (let* ((fbinding-bres + (dynamic-parse-formal f-env (car fst-bind))) + (fbind (car fbinding-bres)) + (bres (cdr fbinding-bres)) + (new-expr-asg + (dynamic-parse-expression c-env (cadr fst-bind)))) + (psb + (extend-env-with-binding f-env fbind) + (extend-env-with-binding c-env fbind) + (cons bres var-defs) + (cons new-expr-asg expr-asgs) + (cdr binds))) + (error 'dynamic-parse-sequential-bindings + "Illegal binding: ~s" fst-bind)))) + (else (error 'dynamic-parse-sequential-bindings + "Illegal bindings: ~s" binds)))))) + (let ((env-vdefs-easgs (psb dynamic-empty-env env '() '() bindings))) + (cons (car env-vdefs-easgs) + (cons (reverse (cadr env-vdefs-easgs)) + (reverse (cddr env-vdefs-easgs))))))) + + +; dynamic-parse-letrec + +(define (dynamic-parse-letrec env args) + (if (pair? args) + (let* ((bindings (car args)) + (body (cdr args)) + (env-ast (dynamic-parse-recursive-bindings env bindings)) + (nenv (car env-ast)) + (bresults (cdr env-ast))) + (dynamic-parse-action-letrec-expression + bresults + (dynamic-parse-body (extend-env-with-env env nenv) body))) + (error 'dynamic-parse-letrec "Illegal bindings/body: ~s" args))) + +; dynamic-parse-recursive-bindings + +(define (dynamic-parse-recursive-bindings env bindings) + ;; ***Note***: the list of pairs is returned in reverse unzipped form! + (if (list-of-list-of-2s? bindings) + (let* ((env-formals-asg + (dynamic-parse-formal* (map car bindings))) + (formals-env + (car env-formals-asg)) + (formals-res + (cdr env-formals-asg)) + (exprs-asg + (dynamic-parse-expression* + (extend-env-with-env env formals-env) + (map cadr bindings)))) + (cons + formals-env + (cons formals-res exprs-asg))) + (error 'dynamic-parse-recursive-bindings "Illegal bindings: ~s" bindings))) + + +; dynamic-parse-do + +(define (dynamic-parse-do env args) + ;; parses do-expressions + ;; ***Note***: Not implemented! + (error 'dynamic-parse-do "Nothing yet...")) + +; dynamic-parse-quasiquote + +(define (dynamic-parse-quasiquote env args) + ;; ***Note***: Not implemented! + (error 'dynamic-parse-quasiquote "Nothing yet...")) + + +;; Command + +; dynamic-parse-command + +(define (dynamic-parse-command env c) + (if (pair? c) + (let ((op (car c)) + (args (cdr c))) + (case op + ((define) (dynamic-parse-define env args)) +; ((begin) (dynamic-parse-command* env args)) ;; AKW + ((begin) (dynamic-parse-action-begin-expression (dynamic-parse-command* env args))) + (else (dynamic-parse-expression env c)))) + (dynamic-parse-expression env c))) + + +; dynamic-parse-command* + +(define (dynamic-parse-command* env commands) + ;; parses a sequence of commands + (if (list? commands) + (map (lambda (command) (dynamic-parse-command env command)) commands) + (error 'dynamic-parse-command* "Invalid sequence of commands: ~s" commands))) + + +; dynamic-parse-define + +(define (dynamic-parse-define env args) + ;; three cases -- see IEEE Scheme, sect. 5.2 + ;; ***Note***: the parser admits forms (define (x . y) ...) + ;; ***Note***: Variables are treated as applied occurrences! + (if (pair? args) + (let ((pattern (car args)) + (exp-or-body (cdr args))) + (cond + ((symbol? pattern) + (if (list-of-1? exp-or-body) + (dynamic-parse-action-definition + (dynamic-parse-variable env pattern) + (dynamic-parse-expression env (car exp-or-body))) + (error 'dynamic-parse-define "Not a single expression: ~s" exp-or-body))) + ((pair? pattern) + (let* ((function-name (car pattern)) + (function-arg-names (cdr pattern)) + (env-ast (dynamic-parse-formals function-arg-names)) + (formals-env (car env-ast)) + (formals-ast (cdr env-ast))) + (dynamic-parse-action-function-definition + (dynamic-parse-variable env function-name) + formals-ast + (dynamic-parse-body (extend-env-with-env env formals-env) exp-or-body)))) + (else (error 'dynamic-parse-define "Not a valid pattern: ~s" pattern)))) + (error 'dynamic-parse-define "Not a valid definition: ~s" args))) + +;; Auxiliary routines + +; forall? + +(define (forall? pred list) + (if (null? list) + #t + (and (pred (car list)) (forall? pred (cdr list))))) + +; list-of-1? + +(define (list-of-1? l) + (and (pair? l) (null? (cdr l)))) + +; list-of-2? + +(define (list-of-2? l) + (and (pair? l) (pair? (cdr l)) (null? (cddr l)))) + +; list-of-3? + +(define (list-of-3? l) + (and (pair? l) (pair? (cdr l)) (pair? (cddr l)) (null? (cdddr l)))) + +; list-of-list-of-2s? + +(define (list-of-list-of-2s? e) + (cond + ((null? e) + #t) + ((pair? e) + (and (list-of-2? (car e)) (list-of-list-of-2s? (cdr e)))) + (else #f))) + + +;; File processing + +; dynamic-parse-from-port + +(define (dynamic-parse-from-port port) + (let ((next-input (read port))) + (if (eof-object? next-input) + '() + (dynamic-parse-action-commands + (dynamic-parse-command dynamic-empty-env next-input) + (dynamic-parse-from-port port))))) + +; dynamic-parse-file + +(define (dynamic-parse-file file-name) + (let ((input-port (open-input-file file-name))) + (dynamic-parse-from-port input-port))) +;---------------------------------------------------------------------------- +; Implementation of Union/find data structure in Scheme +;---------------------------------------------------------------------------- + +;; for union/find the following attributes are necessary: rank, parent +;; (see Tarjan, "Data structures and network algorithms", 1983) +;; In the Scheme realization an element is represented as a single +;; cons cell; its address is the element itself; the car field contains +;; the parent, the cdr field is an address for a cons +;; cell containing the rank (car field) and the information (cdr field) + + +;; general union/find data structure +;; +;; gen-element: Info -> Elem +;; find: Elem -> Elem +;; link: Elem! x Elem! -> Elem +;; asymm-link: Elem! x Elem! -> Elem +;; info: Elem -> Info +;; set-info!: Elem! x Info -> Void + + +(define (gen-element info) + ; generates a new element: the parent field is initialized to '(), + ; the rank field to 0 + (cons '() (cons 0 info))) + +(define info (lambda (l) (cddr l))) + ; returns the information stored in an element + +(define (set-info! elem info) + ; sets the info-field of elem to info + (set-cdr! (cdr elem) info)) + +; (define (find! x) +; ; finds the class representative of x and sets the parent field +; ; directly to the class representative (a class representative has +; ; '() as its parent) (uses path halving) +; ;(display "Find!: ") +; ;(display (pretty-print (info x))) +; ;(newline) +; (let ((px (car x))) +; (if (null? px) +; x +; (let ((ppx (car px))) +; (if (null? ppx) +; px +; (begin +; (set-car! x ppx) +; (find! ppx))))))) + +(define (find! elem) + ; finds the class representative of elem and sets the parent field + ; directly to the class representative (a class representative has + ; '() as its parent) + ;(display "Find!: ") + ;(display (pretty-print (info elem))) + ;(newline) + (let ((p-elem (car elem))) + (if (null? p-elem) + elem + (let ((rep-elem (find! p-elem))) + (set-car! elem rep-elem) + rep-elem)))) + +(define (link! elem-1 elem-2) + ; links class elements by rank + ; they must be distinct class representatives + ; returns the class representative of the merged equivalence classes + ;(display "Link!: ") + ;(display (pretty-print (list (info elem-1) (info elem-2)))) + ;(newline) + (let ((rank-1 (cadr elem-1)) + (rank-2 (cadr elem-2))) + (cond + ((= rank-1 rank-2) + (set-car! (cdr elem-2) (+ rank-2 1)) + (set-car! elem-1 elem-2) + elem-2) + ((> rank-1 rank-2) + (set-car! elem-2 elem-1) + elem-1) + (else + (set-car! elem-1 elem-2) + elem-2)))) + +(define asymm-link! (lambda (l x) (set-car! l x))) + +;(define (asymm-link! elem-1 elem-2) + ; links elem-1 onto elem-2 no matter what rank; + ; does not update the rank of elem-2 and does not return a value + ; the two arguments must be distinct + ;(display "AsymmLink: ") + ;(display (pretty-print (list (info elem-1) (info elem-2)))) + ;(newline) + ;(set-car! elem-1 elem-2)) + +;---------------------------------------------------------------------------- +; Type management +;---------------------------------------------------------------------------- + +; introduces type variables and types for Scheme, + + +;; type TVar (type variables) +;; +;; gen-tvar: () -> TVar +;; gen-type: TCon x TVar* -> TVar +;; dynamic: TVar +;; tvar-id: TVar -> Symbol +;; tvar-def: TVar -> Type + Null +;; tvar-show: TVar -> Symbol* +;; +;; set-def!: !TVar x TCon x TVar* -> Null +;; equiv!: !TVar x !TVar -> Null +;; +;; +;; type TCon (type constructors) +;; +;; ... +;; +;; type Type (types) +;; +;; gen-type: TCon x TVar* -> Type +;; type-con: Type -> TCon +;; type-args: Type -> TVar* +;; +;; boolean: TVar +;; character: TVar +;; null: TVar +;; pair: TVar x TVar -> TVar +;; procedure: TVar x TVar* -> TVar +;; charseq: TVar +;; symbol: TVar +;; array: TVar -> TVar + + +; Needed packages: union/find + +;(load "union-fi.so") + +; TVar + +(define counter 0) +; counter for generating tvar id's + +(define (gen-id) + ; generates a new id (for printing purposes) + (set! counter (+ counter 1)) + counter) + +(define (gen-tvar) + ; generates a new type variable from a new symbol + ; uses union/find elements with two info fields + ; a type variable has exactly four fields: + ; car: TVar (the parent field; initially null) + ; cadr: Number (the rank field; is always nonnegative) + ; caddr: Symbol (the type variable identifier; used only for printing) + ; cdddr: Type (the leq field; initially null) + (gen-element (cons (gen-id) '()))) + +(define (gen-type tcon targs) + ; generates a new type variable with an associated type definition + (gen-element (cons (gen-id) (cons tcon targs)))) + +(define dynamic (gen-element (cons 0 '()))) +; the special type variable dynamic +; Generic operations + +(define (tvar-id tvar) + ; returns the (printable) symbol representing the type variable + (car (info tvar))) + +(define (tvar-def tvar) + ; returns the type definition (if any) of the type variable + (cdr (info tvar))) + +(define (set-def! tvar tcon targs) + ; sets the type definition part of tvar to type + (set-cdr! (info tvar) (cons tcon targs)) + '()) + +(define (reset-def! tvar) + ; resets the type definition part of tvar to nil + (set-cdr! (info tvar) '())) + +(define type-con (lambda (l) (car l))) +; returns the type constructor of a type definition + +(define type-args (lambda (l) (cdr l))) +; returns the type variables of a type definition + +(define (tvar->string tvar) + ; converts a tvar's id to a string + (if (eqv? (tvar-id tvar) 0) + "Dynamic" + (string-append "t#" (number->string (tvar-id tvar) 10)))) + +(define (tvar-show tv) + ; returns a printable list representation of type variable tv + (let* ((tv-rep (find! tv)) + (tv-def (tvar-def tv-rep))) + (cons (tvar->string tv-rep) + (if (null? tv-def) + '() + (cons 'is (type-show tv-def)))))) + +(define (type-show type) + ; returns a printable list representation of type definition type + (cond + ((eqv? (type-con type) ptype-con) + (let ((new-tvar (gen-tvar))) + (cons ptype-con + (cons (tvar-show new-tvar) + (tvar-show ((type-args type) new-tvar)))))) + (else + (cons (type-con type) + (map (lambda (tv) + (tvar->string (find! tv))) + (type-args type)))))) + + + +; Special type operations + +; type constructor literals + +(define boolean-con 'boolean) +(define char-con 'char) +(define null-con 'null) +(define number-con 'number) +(define pair-con 'pair) +(define procedure-con 'procedure) +(define string-con 'string) +(define symbol-con 'symbol) +(define vector-con 'vector) + +; type constants and type constructors + +(define (null) + ; ***Note***: Temporarily changed to be a pair! + ; (gen-type null-con '()) + (pair (gen-tvar) (gen-tvar))) +(define (boolean) + (gen-type boolean-con '())) +(define (character) + (gen-type char-con '())) +(define (number) + (gen-type number-con '())) +(define (charseq) + (gen-type string-con '())) +(define (symbol) + (gen-type symbol-con '())) +(define (pair tvar-1 tvar-2) + (gen-type pair-con (list tvar-1 tvar-2))) +(define (array tvar) + (gen-type vector-con (list tvar))) +(define (procedure arg-tvar res-tvar) + (gen-type procedure-con (list arg-tvar res-tvar))) + + +; equivalencing of type variables + +(define (equiv! tv1 tv2) + (let* ((tv1-rep (find! tv1)) + (tv2-rep (find! tv2)) + (tv1-def (tvar-def tv1-rep)) + (tv2-def (tvar-def tv2-rep))) + (cond + ((eqv? tv1-rep tv2-rep) + '()) + ((eqv? tv2-rep dynamic) + (equiv-with-dynamic! tv1-rep)) + ((eqv? tv1-rep dynamic) + (equiv-with-dynamic! tv2-rep)) + ((null? tv1-def) + (if (null? tv2-def) + ; both tv1 and tv2 are distinct type variables + (link! tv1-rep tv2-rep) + ; tv1 is a type variable, tv2 is a (nondynamic) type + (asymm-link! tv1-rep tv2-rep))) + ((null? tv2-def) + ; tv1 is a (nondynamic) type, tv2 is a type variable + (asymm-link! tv2-rep tv1-rep)) + ((eqv? (type-con tv1-def) (type-con tv2-def)) + ; both tv1 and tv2 are (nondynamic) types with equal numbers of + ; arguments + (link! tv1-rep tv2-rep) + (map equiv! (type-args tv1-def) (type-args tv2-def))) + (else + ; tv1 and tv2 are types with distinct type constructors or different + ; numbers of arguments + (equiv-with-dynamic! tv1-rep) + (equiv-with-dynamic! tv2-rep)))) + '()) + +(define (equiv-with-dynamic! tv) + (let ((tv-rep (find! tv))) + (if (not (eqv? tv-rep dynamic)) + (let ((tv-def (tvar-def tv-rep))) + (asymm-link! tv-rep dynamic) + (if (not (null? tv-def)) + (map equiv-with-dynamic! (type-args tv-def)))))) + '()) +;---------------------------------------------------------------------------- +; Polymorphic type management +;---------------------------------------------------------------------------- + +; introduces parametric polymorphic types + + +;; forall: (Tvar -> Tvar) -> TVar +;; fix: (Tvar -> Tvar) -> Tvar +;; +;; instantiate-type: TVar -> TVar + +; type constructor literal for polymorphic types + +(define ptype-con 'forall) + +(define (forall tv-func) + (gen-type ptype-con tv-func)) + +(define (forall2 tv-func2) + (forall (lambda (tv1) + (forall (lambda (tv2) + (tv-func2 tv1 tv2)))))) + +(define (forall3 tv-func3) + (forall (lambda (tv1) + (forall2 (lambda (tv2 tv3) + (tv-func3 tv1 tv2 tv3)))))) + +(define (forall4 tv-func4) + (forall (lambda (tv1) + (forall3 (lambda (tv2 tv3 tv4) + (tv-func4 tv1 tv2 tv3 tv4)))))) + +(define (forall5 tv-func5) + (forall (lambda (tv1) + (forall4 (lambda (tv2 tv3 tv4 tv5) + (tv-func5 tv1 tv2 tv3 tv4 tv5)))))) + + +; (polymorphic) instantiation + +(define (instantiate-type tv) + ; instantiates type tv and returns a generic instance + (let* ((tv-rep (find! tv)) + (tv-def (tvar-def tv-rep))) + (cond + ((null? tv-def) + tv-rep) + ((eqv? (type-con tv-def) ptype-con) + (instantiate-type ((type-args tv-def) (gen-tvar)))) + (else + tv-rep)))) + +(define (fix tv-func) + ; forms a recursive type: the fixed point of type mapping tv-func + (let* ((new-tvar (gen-tvar)) + (inst-tvar (tv-func new-tvar)) + (inst-def (tvar-def inst-tvar))) + (if (null? inst-def) + (error 'fix "Illegal recursive type: ~s" + (list (tvar-show new-tvar) '= (tvar-show inst-tvar))) + (begin + (set-def! new-tvar + (type-con inst-def) + (type-args inst-def)) + new-tvar)))) + + +;---------------------------------------------------------------------------- +; Constraint management +;---------------------------------------------------------------------------- + + +; constraints + +(define gen-constr (lambda (a b) (cons a b))) +; generates an equality between tvar1 and tvar2 + +(define constr-lhs (lambda (c) (car c))) +; returns the left-hand side of a constraint + +(define constr-rhs (lambda (c) (cdr c))) +; returns the right-hand side of a constraint + +(define (constr-show c) + (cons (tvar-show (car c)) + (cons '= + (cons (tvar-show (cdr c)) '())))) + + +; constraint set management + +(define global-constraints '()) + +(define (init-global-constraints!) + (set! global-constraints '())) + +(define (add-constr! lhs rhs) + (set! global-constraints + (cons (gen-constr lhs rhs) global-constraints)) + '()) + +(define (glob-constr-show) + ; returns printable version of global constraints + (map constr-show global-constraints)) + + +; constraint normalization + +; Needed packages: type management + +;(load "typ-mgmt.so") + +(define (normalize-global-constraints!) + (normalize! global-constraints) + (init-global-constraints!)) + +(define (normalize! constraints) + (map (lambda (c) + (equiv! (constr-lhs c) (constr-rhs c))) constraints)) +; ---------------------------------------------------------------------------- +; Abstract syntax definition and parse actions +; ---------------------------------------------------------------------------- + +; Needed packages: ast-gen.ss +;(load "ast-gen.ss") + +;; Abstract syntax +;; +;; VarDef +;; +;; Identifier = Symbol - SyntacticKeywords +;; SyntacticKeywords = { ... } (see Section 7.1, IEEE Scheme Standard) +;; +;; Datum +;; +;; null-const: Null -> Datum +;; boolean-const: Bool -> Datum +;; char-const: Char -> Datum +;; number-const: Number -> Datum +;; string-const: String -> Datum +;; vector-const: Datum* -> Datum +;; pair-const: Datum x Datum -> Datum +;; +;; Expr +;; +;; Datum < Expr +;; +;; var-def: Identifier -> VarDef +;; variable: VarDef -> Expr +;; identifier: Identifier -> Expr +;; procedure-call: Expr x Expr* -> Expr +;; lambda-expression: Formals x Body -> Expr +;; conditional: Expr x Expr x Expr -> Expr +;; assignment: Variable x Expr -> Expr +;; cond-expression: CondClause+ -> Expr +;; case-expression: Expr x CaseClause* -> Expr +;; and-expression: Expr* -> Expr +;; or-expression: Expr* -> Expr +;; let-expression: (VarDef* x Expr*) x Body -> Expr +;; named-let-expression: VarDef x (VarDef* x Expr*) x Body -> Expr +;; let*-expression: (VarDef* x Expr*) x Body -> Expr +;; letrec-expression: (VarDef* x Expr*) x Body -> Expr +;; begin-expression: Expr+ -> Expr +;; do-expression: IterDef* x CondClause x Expr* -> Expr +;; empty: -> Expr +;; +;; VarDef* < Formals +;; +;; simple-formal: VarDef -> Formals +;; dotted-formals: VarDef* x VarDef -> Formals +;; +;; Body = Definition* x Expr+ (reversed) +;; CondClause = Expr x Expr+ +;; CaseClause = Datum* x Expr+ +;; IterDef = VarDef x Expr x Expr +;; +;; Definition +;; +;; definition: Identifier x Expr -> Definition +;; function-definition: Identifier x Formals x Body -> Definition +;; begin-command: Definition* -> Definition +;; +;; Expr < Command +;; Definition < Command +;; +;; Program = Command* + + +;; Abstract syntax operators + +; Datum + +(define null-const 0) +(define boolean-const 1) +(define char-const 2) +(define number-const 3) +(define string-const 4) +(define symbol-const 5) +(define vector-const 6) +(define pair-const 7) + +; Bindings + +(define var-def 8) +(define null-def 29) +(define pair-def 30) + +; Expr + +(define variable 9) +(define identifier 10) +(define procedure-call 11) +(define lambda-expression 12) +(define conditional 13) +(define assignment 14) +(define cond-expression 15) +(define case-expression 16) +(define and-expression 17) +(define or-expression 18) +(define let-expression 19) +(define named-let-expression 20) +(define let*-expression 21) +(define letrec-expression 22) +(define begin-expression 23) +(define do-expression 24) +(define empty 25) +(define null-arg 31) +(define pair-arg 32) + +; Command + +(define definition 26) +(define function-definition 27) +(define begin-command 28) + + +;; Parse actions for abstract syntax construction + +(define (dynamic-parse-action-null-const) + ;; dynamic-parse-action for '() + (ast-gen null-const '())) + +(define (dynamic-parse-action-boolean-const e) + ;; dynamic-parse-action for #f and #t + (ast-gen boolean-const e)) + +(define (dynamic-parse-action-char-const e) + ;; dynamic-parse-action for character constants + (ast-gen char-const e)) + +(define (dynamic-parse-action-number-const e) + ;; dynamic-parse-action for number constants + (ast-gen number-const e)) + +(define (dynamic-parse-action-string-const e) + ;; dynamic-parse-action for string literals + (ast-gen string-const e)) + +(define (dynamic-parse-action-symbol-const e) + ;; dynamic-parse-action for symbol constants + (ast-gen symbol-const e)) + +(define (dynamic-parse-action-vector-const e) + ;; dynamic-parse-action for vector literals + (ast-gen vector-const e)) + +(define (dynamic-parse-action-pair-const e1 e2) + ;; dynamic-parse-action for pairs + (ast-gen pair-const (cons e1 e2))) + +(define (dynamic-parse-action-var-def e) + ;; dynamic-parse-action for defining occurrences of variables; + ;; e is a symbol + (ast-gen var-def e)) + +(define (dynamic-parse-action-null-formal) + ;; dynamic-parse-action for null-list of formals + (ast-gen null-def '())) + +(define (dynamic-parse-action-pair-formal d1 d2) + ;; dynamic-parse-action for non-null list of formals; + ;; d1 is the result of parsing the first formal, + ;; d2 the result of parsing the remaining formals + (ast-gen pair-def (cons d1 d2))) + +(define (dynamic-parse-action-variable e) + ;; dynamic-parse-action for applied occurrences of variables + ;; ***Note***: e is the result of a dynamic-parse-action on the + ;; corresponding variable definition! + (ast-gen variable e)) + +(define (dynamic-parse-action-identifier e) + ;; dynamic-parse-action for undeclared identifiers (free variable + ;; occurrences) + ;; ***Note***: e is a symbol (legal identifier) + (ast-gen identifier e)) + +(define (dynamic-parse-action-null-arg) + ;; dynamic-parse-action for a null list of arguments in a procedure call + (ast-gen null-arg '())) + +(define (dynamic-parse-action-pair-arg a1 a2) + ;; dynamic-parse-action for a non-null list of arguments in a procedure call + ;; a1 is the result of parsing the first argument, + ;; a2 the result of parsing the remaining arguments + (ast-gen pair-arg (cons a1 a2))) + +(define (dynamic-parse-action-procedure-call op args) + ;; dynamic-parse-action for procedure calls: op function, args list of arguments + (ast-gen procedure-call (cons op args))) + +(define (dynamic-parse-action-lambda-expression formals body) + ;; dynamic-parse-action for lambda-abstractions + (ast-gen lambda-expression (cons formals body))) + +(define (dynamic-parse-action-conditional test then-branch else-branch) + ;; dynamic-parse-action for conditionals (if-then-else expressions) + (ast-gen conditional (cons test (cons then-branch else-branch)))) + +(define (dynamic-parse-action-empty) + ;; dynamic-parse-action for missing or empty field + (ast-gen empty '())) + +(define (dynamic-parse-action-assignment lhs rhs) + ;; dynamic-parse-action for assignment + (ast-gen assignment (cons lhs rhs))) + +(define (dynamic-parse-action-begin-expression body) + ;; dynamic-parse-action for begin-expression + (ast-gen begin-expression body)) + +(define (dynamic-parse-action-cond-expression clauses) + ;; dynamic-parse-action for cond-expressions + (ast-gen cond-expression clauses)) + +(define (dynamic-parse-action-and-expression args) + ;; dynamic-parse-action for and-expressions + (ast-gen and-expression args)) + +(define (dynamic-parse-action-or-expression args) + ;; dynamic-parse-action for or-expressions + (ast-gen or-expression args)) + +(define (dynamic-parse-action-case-expression key clauses) + ;; dynamic-parse-action for case-expressions + (ast-gen case-expression (cons key clauses))) + +(define (dynamic-parse-action-let-expression bindings body) + ;; dynamic-parse-action for let-expressions + (ast-gen let-expression (cons bindings body))) + +(define (dynamic-parse-action-named-let-expression variable bindings body) + ;; dynamic-parse-action for named-let expressions + (ast-gen named-let-expression (cons variable (cons bindings body)))) + +(define (dynamic-parse-action-let*-expression bindings body) + ;; dynamic-parse-action for let-expressions + (ast-gen let*-expression (cons bindings body))) + +(define (dynamic-parse-action-letrec-expression bindings body) + ;; dynamic-parse-action for let-expressions + (ast-gen letrec-expression (cons bindings body))) + +(define (dynamic-parse-action-definition variable expr) + ;; dynamic-parse-action for simple definitions + (ast-gen definition (cons variable expr))) + +(define (dynamic-parse-action-function-definition variable formals body) + ;; dynamic-parse-action for function definitions + (ast-gen function-definition (cons variable (cons formals body)))) + + +(define dynamic-parse-action-commands (lambda (a b) (cons a b))) +;; dynamic-parse-action for processing a command result followed by a the +;; result of processing the remaining commands + + +;; Pretty-printing abstract syntax trees + +(define (ast-show ast) + ;; converts abstract syntax tree to list representation (Scheme program) + ;; ***Note***: check translation of constructors to numbers at the top of the file + (let ((syntax-op (ast-con ast)) + (syntax-arg (ast-arg ast))) + (case syntax-op + ((0 1 2 3 4 8 10) syntax-arg) + ((29 31) '()) + ((30 32) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg)))) + ((5) (list 'quote syntax-arg)) + ((6) (list->vector (map ast-show syntax-arg))) + ((7) (list 'cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg)))) + ((9) (ast-arg syntax-arg)) + ((11) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg)))) + ((12) (cons 'lambda (cons (ast-show (car syntax-arg)) + (map ast-show (cdr syntax-arg))))) + ((13) (cons 'if (cons (ast-show (car syntax-arg)) + (cons (ast-show (cadr syntax-arg)) + (let ((alt (cddr syntax-arg))) + (if (eqv? (ast-con alt) empty) + '() + (list (ast-show alt)))))))) + ((14) (list 'set! (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg)))) + ((15) (cons 'cond + (map (lambda (cc) + (let ((guard (car cc)) + (body (cdr cc))) + (cons + (if (eqv? (ast-con guard) empty) + 'else + (ast-show guard)) + (map ast-show body)))) + syntax-arg))) + ((16) (cons 'case + (cons (ast-show (car syntax-arg)) + (map (lambda (cc) + (let ((data (car cc))) + (if (and (pair? data) + (eqv? (ast-con (car data)) empty)) + (cons 'else + (map ast-show (cdr cc))) + (cons (map datum-show data) + (map ast-show (cdr cc)))))) + (cdr syntax-arg))))) + ((17) (cons 'and (map ast-show syntax-arg))) + ((18) (cons 'or (map ast-show syntax-arg))) + ((19) (cons 'let + (cons (map + (lambda (vd e) + (list (ast-show vd) (ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map ast-show (cdr syntax-arg))))) + ((20) (cons 'let + (cons (ast-show (car syntax-arg)) + (cons (map + (lambda (vd e) + (list (ast-show vd) (ast-show e))) + (caadr syntax-arg) + (cdadr syntax-arg)) + (map ast-show (cddr syntax-arg)))))) + ((21) (cons 'let* + (cons (map + (lambda (vd e) + (list (ast-show vd) (ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map ast-show (cdr syntax-arg))))) + ((22) (cons 'letrec + (cons (map + (lambda (vd e) + (list (ast-show vd) (ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map ast-show (cdr syntax-arg))))) + ((23) (cons 'begin + (map ast-show syntax-arg))) + ((24) (error 'ast-show "Do expressions not handled! (~s)" syntax-arg)) + ((25) (error 'ast-show "This can't happen: empty encountered!")) + ((26) (list 'define + (ast-show (car syntax-arg)) + (ast-show (cdr syntax-arg)))) + ((27) (cons 'define + (cons + (cons (ast-show (car syntax-arg)) + (ast-show (cadr syntax-arg))) + (map ast-show (cddr syntax-arg))))) + ((28) (cons 'begin + (map ast-show syntax-arg))) + (else (error 'ast-show "Unknown abstract syntax operator: ~s" + syntax-op))))) + + +;; ast*-show + +(define (ast*-show p) + ;; shows a list of abstract syntax trees + (map ast-show p)) + + +;; datum-show + +(define (datum-show ast) + ;; prints an abstract syntax tree as a datum + (case (ast-con ast) + ((0 1 2 3 4 5) (ast-arg ast)) + ((6) (list->vector (map datum-show (ast-arg ast)))) + ((7) (cons (datum-show (car (ast-arg ast))) (datum-show (cdr (ast-arg ast))))) + (else (error 'datum-show "This should not happen!")))) + +; write-to-port + +(define (write-to-port prog port) + ; writes a program to a port + (for-each + (lambda (command) + (write command port) + (newline port)) + prog) + '()) + +; write-file + +(define (write-to-file prog filename) + ; write a program to a file + (let ((port (open-output-file filename))) + (write-to-port prog port) + (close-output-port port) + '())) + +; ---------------------------------------------------------------------------- +; Typed abstract syntax tree management: constraint generation, display, etc. +; ---------------------------------------------------------------------------- + + +;; Abstract syntax operations, incl. constraint generation + +(define (ast-gen syntax-op arg) + ; generates all attributes and performs semantic side effects + (let ((ntvar + (case syntax-op + ((0 29 31) (null)) + ((1) (boolean)) + ((2) (character)) + ((3) (number)) + ((4) (charseq)) + ((5) (symbol)) + ((6) (let ((aux-tvar (gen-tvar))) + (for-each (lambda (t) + (add-constr! t aux-tvar)) + (map ast-tvar arg)) + (array aux-tvar))) + ((7 30 32) (let ((t1 (ast-tvar (car arg))) + (t2 (ast-tvar (cdr arg)))) + (pair t1 t2))) + ((8) (gen-tvar)) + ((9) (ast-tvar arg)) + ((10) (let ((in-env (dynamic-lookup arg dynamic-top-level-env))) + (if in-env + (instantiate-type (binding-value in-env)) + (let ((new-tvar (gen-tvar))) + (set! dynamic-top-level-env (extend-env-with-binding + dynamic-top-level-env + (gen-binding arg new-tvar))) + new-tvar)))) + ((11) (let ((new-tvar (gen-tvar))) + (add-constr! (procedure (ast-tvar (cdr arg)) new-tvar) + (ast-tvar (car arg))) + new-tvar)) + ((12) (procedure (ast-tvar (car arg)) + (ast-tvar (tail (cdr arg))))) + ((13) (let ((t-test (ast-tvar (car arg))) + (t-consequent (ast-tvar (cadr arg))) + (t-alternate (ast-tvar (cddr arg)))) + (add-constr! (boolean) t-test) + (add-constr! t-consequent t-alternate) + t-consequent)) + ((14) (let ((var-tvar (ast-tvar (car arg))) + (exp-tvar (ast-tvar (cdr arg)))) + (add-constr! var-tvar exp-tvar) + var-tvar)) + ((15) (let ((new-tvar (gen-tvar))) + (for-each (lambda (body) + (add-constr! (ast-tvar (tail body)) new-tvar)) + (map cdr arg)) + (for-each (lambda (e) + (add-constr! (boolean) (ast-tvar e))) + (map car arg)) + new-tvar)) + ((16) (let* ((new-tvar (gen-tvar)) + (t-key (ast-tvar (car arg))) + (case-clauses (cdr arg))) + (for-each (lambda (exprs) + (for-each (lambda (e) + (add-constr! (ast-tvar e) t-key)) + exprs)) + (map car case-clauses)) + (for-each (lambda (body) + (add-constr! (ast-tvar (tail body)) new-tvar)) + (map cdr case-clauses)) + new-tvar)) + ((17 18) (for-each (lambda (e) + (add-constr! (boolean) (ast-tvar e))) + arg) + (boolean)) + ((19 21 22) (let ((var-def-tvars (map ast-tvar (caar arg))) + (def-expr-types (map ast-tvar (cdar arg))) + (body-type (ast-tvar (tail (cdr arg))))) + (for-each add-constr! var-def-tvars def-expr-types) + body-type)) + ((20) (let ((var-def-tvars (map ast-tvar (caadr arg))) + (def-expr-types (map ast-tvar (cdadr arg))) + (body-type (ast-tvar (tail (cddr arg)))) + (named-var-type (ast-tvar (car arg)))) + (for-each add-constr! var-def-tvars def-expr-types) + (add-constr! (procedure (convert-tvars var-def-tvars) body-type) + named-var-type) + body-type)) + ((23) (ast-tvar (tail arg))) + ((24) (error 'ast-gen + "Do-expressions not handled! (Argument: ~s) arg")) + ((25) (gen-tvar)) + ((26) (let ((t-var (ast-tvar (car arg))) + (t-exp (ast-tvar (cdr arg)))) + (add-constr! t-var t-exp) + t-var)) + ((27) (let ((t-var (ast-tvar (car arg))) + (t-formals (ast-tvar (cadr arg))) + (t-body (ast-tvar (tail (cddr arg))))) + (add-constr! (procedure t-formals t-body) t-var) + t-var)) + ((28) (gen-tvar)) + (else (error 'ast-gen "Can't handle syntax operator: ~s" syntax-op))))) + (cons syntax-op (cons ntvar arg)))) + +(define ast-con car) +;; extracts the ast-constructor from an abstract syntax tree + +(define ast-arg cddr) +;; extracts the ast-argument from an abstract syntax tree + +(define ast-tvar cadr) +;; extracts the tvar from an abstract syntax tree + + +;; tail + +(define (tail l) + ;; returns the tail of a nonempty list + (if (null? (cdr l)) + (car l) + (tail (cdr l)))) + +; convert-tvars + +(define (convert-tvars tvar-list) + ;; converts a list of tvars to a single tvar + (cond + ((null? tvar-list) (null)) + ((pair? tvar-list) (pair (car tvar-list) + (convert-tvars (cdr tvar-list)))) + (else (error 'convert-tvars "Not a list of tvars: ~s" tvar-list)))) + + +;; Pretty-printing abstract syntax trees + +(define (tast-show ast) + ;; converts abstract syntax tree to list representation (Scheme program) + (let ((syntax-op (ast-con ast)) + (syntax-tvar (tvar-show (ast-tvar ast))) + (syntax-arg (ast-arg ast))) + (cons + (case syntax-op + ((0 1 2 3 4 8 10) syntax-arg) + ((29 31) '()) + ((30 32) (cons (tast-show (car syntax-arg)) + (tast-show (cdr syntax-arg)))) + ((5) (list 'quote syntax-arg)) + ((6) (list->vector (map tast-show syntax-arg))) + ((7) (list 'cons (tast-show (car syntax-arg)) + (tast-show (cdr syntax-arg)))) + ((9) (ast-arg syntax-arg)) + ((11) (cons (tast-show (car syntax-arg)) (tast-show (cdr syntax-arg)))) + ((12) (cons 'lambda (cons (tast-show (car syntax-arg)) + (map tast-show (cdr syntax-arg))))) + ((13) (cons 'if (cons (tast-show (car syntax-arg)) + (cons (tast-show (cadr syntax-arg)) + (let ((alt (cddr syntax-arg))) + (if (eqv? (ast-con alt) empty) + '() + (list (tast-show alt)))))))) + ((14) (list 'set! (tast-show (car syntax-arg)) + (tast-show (cdr syntax-arg)))) + ((15) (cons 'cond + (map (lambda (cc) + (let ((guard (car cc)) + (body (cdr cc))) + (cons + (if (eqv? (ast-con guard) empty) + 'else + (tast-show guard)) + (map tast-show body)))) + syntax-arg))) + ((16) (cons 'case + (cons (tast-show (car syntax-arg)) + (map (lambda (cc) + (let ((data (car cc))) + (if (and (pair? data) + (eqv? (ast-con (car data)) empty)) + (cons 'else + (map tast-show (cdr cc))) + (cons (map datum-show data) + (map tast-show (cdr cc)))))) + (cdr syntax-arg))))) + ((17) (cons 'and (map tast-show syntax-arg))) + ((18) (cons 'or (map tast-show syntax-arg))) + ((19) (cons 'let + (cons (map + (lambda (vd e) + (list (tast-show vd) (tast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tast-show (cdr syntax-arg))))) + ((20) (cons 'let + (cons (tast-show (car syntax-arg)) + (cons (map + (lambda (vd e) + (list (tast-show vd) (tast-show e))) + (caadr syntax-arg) + (cdadr syntax-arg)) + (map tast-show (cddr syntax-arg)))))) + ((21) (cons 'let* + (cons (map + (lambda (vd e) + (list (tast-show vd) (tast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tast-show (cdr syntax-arg))))) + ((22) (cons 'letrec + (cons (map + (lambda (vd e) + (list (tast-show vd) (tast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tast-show (cdr syntax-arg))))) + ((23) (cons 'begin + (map tast-show syntax-arg))) + ((24) (error 'tast-show "Do expressions not handled! (~s)" syntax-arg)) + ((25) (error 'tast-show "This can't happen: empty encountered!")) + ((26) (list 'define + (tast-show (car syntax-arg)) + (tast-show (cdr syntax-arg)))) + ((27) (cons 'define + (cons + (cons (tast-show (car syntax-arg)) + (tast-show (cadr syntax-arg))) + (map tast-show (cddr syntax-arg))))) + ((28) (cons 'begin + (map tast-show syntax-arg))) + (else (error 'tast-show "Unknown abstract syntax operator: ~s" + syntax-op))) + syntax-tvar))) + +;; tast*-show + +(define (tast*-show p) + ;; shows a list of abstract syntax trees + (map tast-show p)) + + +;; counters for tagging/untagging + +(define untag-counter 0) +(define no-untag-counter 0) +(define tag-counter 0) +(define no-tag-counter 0) +(define may-untag-counter 0) +(define no-may-untag-counter 0) + +(define (reset-counters!) + (set! untag-counter 0) + (set! no-untag-counter 0) + (set! tag-counter 0) + (set! no-tag-counter 0) + (set! may-untag-counter 0) + (set! no-may-untag-counter 0)) + +(define (counters-show) + (list + (cons tag-counter no-tag-counter) + (cons untag-counter no-untag-counter) + (cons may-untag-counter no-may-untag-counter))) + + +;; tag-show + +(define (tag-show tvar-rep prog) + ; display prog with tagging operation + (if (eqv? tvar-rep dynamic) + (begin + (set! tag-counter (+ tag-counter 1)) + (list 'tag prog)) + (begin + (set! no-tag-counter (+ no-tag-counter 1)) + (list 'no-tag prog)))) + + +;; untag-show + +(define (untag-show tvar-rep prog) + ; display prog with untagging operation + (if (eqv? tvar-rep dynamic) + (begin + (set! untag-counter (+ untag-counter 1)) + (list 'untag prog)) + (begin + (set! no-untag-counter (+ no-untag-counter 1)) + (list 'no-untag prog)))) + +(define (may-untag-show tvar-rep prog) + ; display possible untagging in actual arguments + (if (eqv? tvar-rep dynamic) + (begin + (set! may-untag-counter (+ may-untag-counter 1)) + (list 'may-untag prog)) + (begin + (set! no-may-untag-counter (+ no-may-untag-counter 1)) + (list 'no-may-untag prog)))) + + +;; tag-ast-show + +(define (tag-ast-show ast) + ;; converts typed and normalized abstract syntax tree to + ;; a Scheme program with explicit tagging and untagging operations + (let ((syntax-op (ast-con ast)) + (syntax-tvar (find! (ast-tvar ast))) + (syntax-arg (ast-arg ast))) + (case syntax-op + ((0 1 2 3 4) + (tag-show syntax-tvar syntax-arg)) + ((8 10) syntax-arg) + ((29 31) '()) + ((30) (cons (tag-ast-show (car syntax-arg)) + (tag-ast-show (cdr syntax-arg)))) + ((32) (cons (may-untag-show (find! (ast-tvar (car syntax-arg))) + (tag-ast-show (car syntax-arg))) + (tag-ast-show (cdr syntax-arg)))) + ((5) (tag-show syntax-tvar (list 'quote syntax-arg))) + ((6) (tag-show syntax-tvar (list->vector (map tag-ast-show syntax-arg)))) + ((7) (tag-show syntax-tvar (list 'cons (tag-ast-show (car syntax-arg)) + (tag-ast-show (cdr syntax-arg))))) + ((9) (ast-arg syntax-arg)) + ((11) (let ((proc-tvar (find! (ast-tvar (car syntax-arg))))) + (cons (untag-show proc-tvar + (tag-ast-show (car syntax-arg))) + (tag-ast-show (cdr syntax-arg))))) + ((12) (tag-show syntax-tvar + (cons 'lambda (cons (tag-ast-show (car syntax-arg)) + (map tag-ast-show (cdr syntax-arg)))))) + ((13) (let ((test-tvar (find! (ast-tvar (car syntax-arg))))) + (cons 'if (cons (untag-show test-tvar + (tag-ast-show (car syntax-arg))) + (cons (tag-ast-show (cadr syntax-arg)) + (let ((alt (cddr syntax-arg))) + (if (eqv? (ast-con alt) empty) + '() + (list (tag-ast-show alt))))))))) + ((14) (list 'set! (tag-ast-show (car syntax-arg)) + (tag-ast-show (cdr syntax-arg)))) + ((15) (cons 'cond + (map (lambda (cc) + (let ((guard (car cc)) + (body (cdr cc))) + (cons + (if (eqv? (ast-con guard) empty) + 'else + (untag-show (find! (ast-tvar guard)) + (tag-ast-show guard))) + (map tag-ast-show body)))) + syntax-arg))) + ((16) (cons 'case + (cons (tag-ast-show (car syntax-arg)) + (map (lambda (cc) + (let ((data (car cc))) + (if (and (pair? data) + (eqv? (ast-con (car data)) empty)) + (cons 'else + (map tag-ast-show (cdr cc))) + (cons (map datum-show data) + (map tag-ast-show (cdr cc)))))) + (cdr syntax-arg))))) + ((17) (cons 'and (map + (lambda (ast) + (let ((bool-tvar (find! (ast-tvar ast)))) + (untag-show bool-tvar (tag-ast-show ast)))) + syntax-arg))) + ((18) (cons 'or (map + (lambda (ast) + (let ((bool-tvar (find! (ast-tvar ast)))) + (untag-show bool-tvar (tag-ast-show ast)))) + syntax-arg))) + ((19) (cons 'let + (cons (map + (lambda (vd e) + (list (tag-ast-show vd) (tag-ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tag-ast-show (cdr syntax-arg))))) + ((20) (cons 'let + (cons (tag-ast-show (car syntax-arg)) + (cons (map + (lambda (vd e) + (list (tag-ast-show vd) (tag-ast-show e))) + (caadr syntax-arg) + (cdadr syntax-arg)) + (map tag-ast-show (cddr syntax-arg)))))) + ((21) (cons 'let* + (cons (map + (lambda (vd e) + (list (tag-ast-show vd) (tag-ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tag-ast-show (cdr syntax-arg))))) + ((22) (cons 'letrec + (cons (map + (lambda (vd e) + (list (tag-ast-show vd) (tag-ast-show e))) + (caar syntax-arg) + (cdar syntax-arg)) + (map tag-ast-show (cdr syntax-arg))))) + ((23) (cons 'begin + (map tag-ast-show syntax-arg))) + ((24) (error 'tag-ast-show "Do expressions not handled! (~s)" syntax-arg)) + ((25) (error 'tag-ast-show "This can't happen: empty encountered!")) + ((26) (list 'define + (tag-ast-show (car syntax-arg)) + (tag-ast-show (cdr syntax-arg)))) + ((27) (let ((func-tvar (find! (ast-tvar (car syntax-arg))))) + (list 'define + (tag-ast-show (car syntax-arg)) + (tag-show func-tvar + (cons 'lambda + (cons (tag-ast-show (cadr syntax-arg)) + (map tag-ast-show (cddr syntax-arg)))))))) + ((28) (cons 'begin + (map tag-ast-show syntax-arg))) + (else (error 'tag-ast-show "Unknown abstract syntax operator: ~s" + syntax-op))))) + + +; tag-ast*-show + +(define (tag-ast*-show p) + ; display list of commands/expressions with tagging/untagging + ; operations + (map tag-ast-show p)) +; ---------------------------------------------------------------------------- +; Top level type environment +; ---------------------------------------------------------------------------- + + +; Needed packages: type management (monomorphic and polymorphic) + +;(load "typ-mgmt.ss") +;(load "ptyp-mgm.ss") + + +; type environment for miscellaneous + +(define misc-env + (list + (cons 'quote (forall (lambda (tv) tv))) + (cons 'eqv? (forall (lambda (tv) (procedure (convert-tvars (list tv tv)) + (boolean))))) + (cons 'eq? (forall (lambda (tv) (procedure (convert-tvars (list tv tv)) + (boolean))))) + (cons 'equal? (forall (lambda (tv) (procedure (convert-tvars (list tv tv)) + (boolean))))) + )) + +; type environment for input/output + +(define io-env + (list + (cons 'open-input-file (procedure (convert-tvars (list (charseq))) dynamic)) + (cons 'eof-object? (procedure (convert-tvars (list dynamic)) (boolean))) + (cons 'read (forall (lambda (tv) + (procedure (convert-tvars (list tv)) dynamic)))) + (cons 'write (forall (lambda (tv) + (procedure (convert-tvars (list tv)) dynamic)))) + (cons 'display (forall (lambda (tv) + (procedure (convert-tvars (list tv)) dynamic)))) + (cons 'newline (procedure (null) dynamic)) + (cons 'pretty-print (forall (lambda (tv) + (procedure (convert-tvars (list tv)) dynamic)))))) + + +; type environment for Booleans + +(define boolean-env + (list + (cons 'boolean? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + ;(cons #f (boolean)) + ; #f doesn't exist in Chez Scheme, but gets mapped to null! + (cons #t (boolean)) + (cons 'not (procedure (convert-tvars (list (boolean))) (boolean))) + )) + + +; type environment for pairs and lists + +(define (list-type tv) + (fix (lambda (tv2) (pair tv tv2)))) + +(define list-env + (list + (cons 'pair? (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2))) + (boolean))))) + (cons 'null? (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2))) + (boolean))))) + (cons 'list? (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2))) + (boolean))))) + (cons 'cons (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list tv1 tv2)) + (pair tv1 tv2))))) + (cons 'car (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2))) + tv1)))) + (cons 'cdr (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2))) + tv2)))) + (cons 'set-car! (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2) + tv1)) + dynamic)))) + (cons 'set-cdr! (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars (list (pair tv1 tv2) + tv2)) + dynamic)))) + (cons 'caar (forall3 (lambda (tv1 tv2 tv3) + (procedure (convert-tvars + (list (pair (pair tv1 tv2) tv3))) + tv1)))) + (cons 'cdar (forall3 (lambda (tv1 tv2 tv3) + (procedure (convert-tvars + (list (pair (pair tv1 tv2) tv3))) + tv2)))) + + (cons 'cadr (forall3 (lambda (tv1 tv2 tv3) + (procedure (convert-tvars + (list (pair tv1 (pair tv2 tv3)))) + tv2)))) + (cons 'cddr (forall3 (lambda (tv1 tv2 tv3) + (procedure (convert-tvars + (list (pair tv1 (pair tv2 tv3)))) + tv3)))) + (cons 'caaar (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair (pair (pair tv1 tv2) tv3) tv4))) + tv1)))) + (cons 'cdaar (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair (pair (pair tv1 tv2) tv3) tv4))) + tv2)))) + (cons 'cadar (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair (pair tv1 (pair tv2 tv3)) tv4))) + tv2)))) + (cons 'cddar (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair (pair tv1 (pair tv2 tv3)) tv4))) + tv3)))) + (cons 'caadr (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair tv1 (pair (pair tv2 tv3) tv4)))) + tv2)))) + (cons 'cdadr (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair tv1 (pair (pair tv2 tv3) tv4)))) + tv3)))) + (cons 'caddr (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair tv1 (pair tv2 (pair tv3 tv4))))) + tv3)))) + (cons 'cdddr (forall4 + (lambda (tv1 tv2 tv3 tv4) + (procedure (convert-tvars + (list (pair tv1 (pair tv2 (pair tv3 tv4))))) + tv4)))) + (cons 'cadddr + (forall5 (lambda (tv1 tv2 tv3 tv4 tv5) + (procedure (convert-tvars + (list (pair tv1 + (pair tv2 + (pair tv3 + (pair tv4 tv5)))))) + tv4)))) + (cons 'cddddr + (forall5 (lambda (tv1 tv2 tv3 tv4 tv5) + (procedure (convert-tvars + (list (pair tv1 + (pair tv2 + (pair tv3 + (pair tv4 tv5)))))) + tv5)))) + (cons 'list (forall (lambda (tv) + (procedure tv tv)))) + (cons 'length (forall (lambda (tv) + (procedure (convert-tvars (list (list-type tv))) + (number))))) + (cons 'append (forall (lambda (tv) + (procedure (convert-tvars (list (list-type tv) + (list-type tv))) + (list-type tv))))) + (cons 'reverse (forall (lambda (tv) + (procedure (convert-tvars (list (list-type tv))) + (list-type tv))))) + (cons 'list-ref (forall (lambda (tv) + (procedure (convert-tvars (list (list-type tv) + (number))) + tv)))) + (cons 'memq (forall (lambda (tv) + (procedure (convert-tvars (list tv + (list-type tv))) + (boolean))))) + (cons 'memv (forall (lambda (tv) + (procedure (convert-tvars (list tv + (list-type tv))) + (boolean))))) + (cons 'member (forall (lambda (tv) + (procedure (convert-tvars (list tv + (list-type tv))) + (boolean))))) + (cons 'assq (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list tv1 + (list-type (pair tv1 tv2)))) + (pair tv1 tv2))))) + (cons 'assv (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list tv1 + (list-type (pair tv1 tv2)))) + (pair tv1 tv2))))) + (cons 'assoc (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list tv1 + (list-type (pair tv1 tv2)))) + (pair tv1 tv2))))) + )) + + +(define symbol-env + (list + (cons 'symbol? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + (cons 'symbol->string (procedure (convert-tvars (list (symbol))) (charseq))) + (cons 'string->symbol (procedure (convert-tvars (list (charseq))) (symbol))) + )) + +(define number-env + (list + (cons 'number? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + (cons '+ (procedure (convert-tvars (list (number) (number))) (number))) + (cons '- (procedure (convert-tvars (list (number) (number))) (number))) + (cons '* (procedure (convert-tvars (list (number) (number))) (number))) + (cons '/ (procedure (convert-tvars (list (number) (number))) (number))) + (cons 'number->string (procedure (convert-tvars (list (number))) (charseq))) + (cons 'string->number (procedure (convert-tvars (list (charseq))) (number))) + )) + +(define char-env + (list + (cons 'char? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + (cons 'char->integer (procedure (convert-tvars (list (character))) + (number))) + (cons 'integer->char (procedure (convert-tvars (list (number))) + (character))) + )) + +(define string-env + (list + (cons 'string? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + )) + +(define vector-env + (list + (cons 'vector? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + (cons 'make-vector (forall (lambda (tv) + (procedure (convert-tvars (list (number))) + (array tv))))) + (cons 'vector-length (forall (lambda (tv) + (procedure (convert-tvars (list (array tv))) + (number))))) + (cons 'vector-ref (forall (lambda (tv) + (procedure (convert-tvars (list (array tv) + (number))) + tv)))) + (cons 'vector-set! (forall (lambda (tv) + (procedure (convert-tvars (list (array tv) + (number) + tv)) + dynamic)))) + )) + +(define procedure-env + (list + (cons 'procedure? (forall (lambda (tv) + (procedure (convert-tvars (list tv)) (boolean))))) + (cons 'map (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list (procedure (convert-tvars + (list tv1)) tv2) + (list-type tv1))) + (list-type tv2))))) + (cons 'foreach (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list (procedure (convert-tvars + (list tv1)) tv2) + (list-type tv1))) + (list-type tv2))))) + (cons 'call-with-current-continuation + (forall2 (lambda (tv1 tv2) + (procedure (convert-tvars + (list (procedure + (convert-tvars + (list (procedure (convert-tvars + (list tv1)) tv2))) + tv2))) + tv2)))) + )) + + +; global top level environment + +(define (global-env) + (append misc-env + io-env + boolean-env + symbol-env + number-env + char-env + string-env + vector-env + procedure-env + list-env)) + +(define dynamic-top-level-env (global-env)) + +(define (init-dynamic-top-level-env!) + (set! dynamic-top-level-env (global-env)) + '()) + +(define (dynamic-top-level-env-show) + ; displays the top level environment + (map (lambda (binding) + (cons (key-show (binding-key binding)) + (cons ': (tvar-show (binding-value binding))))) + (env->list dynamic-top-level-env))) +; ---------------------------------------------------------------------------- +; Dynamic type inference for Scheme +; ---------------------------------------------------------------------------- + +; Needed packages: + +(define (ic!) (init-global-constraints!)) +(define (pc) (glob-constr-show)) +(define (lc) (length global-constraints)) +(define (n!) (normalize-global-constraints!)) +(define (pt) (dynamic-top-level-env-show)) +(define (it!) (init-dynamic-top-level-env!)) +(define (io!) (set! tag-ops 0) (set! no-ops 0)) +(define (i!) (ic!) (it!) (io!) '()) + +(define tag-ops 0) +(define no-ops 0) + + +; This wasn't intended to be an i/o benchmark, +; so let's read the file just once. + +(define *forms* + (call-with-input-file + "dynamic-input.txt" + (lambda (port) + (define (loop forms) + (let ((form (read port))) + (if (eof-object? form) + (reverse forms) + (loop (cons form forms))))) + (loop '())))) + +(define (dynamic-parse-forms forms) + (if (null? forms) + '() + (let ((next-input (car forms))) + (dynamic-parse-action-commands + (dynamic-parse-command dynamic-empty-env next-input) + (dynamic-parse-forms (cdr forms)))))) + +(define doit + (lambda () + (i!) + (let ((foo (dynamic-parse-forms *forms*))) + (normalize-global-constraints!) + (reset-counters!) + (tag-ast*-show foo) + (counters-show)))) + +(time (doit)) diff --git a/collects/tests/mzscheme/benchmarks/common/dynamic.ss b/collects/tests/mzscheme/benchmarks/common/dynamic.ss new file mode 100644 index 0000000000..3c51b44d4c --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/dynamic.ss @@ -0,0 +1,2 @@ + +(module dynamic "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/earley.sch b/collects/tests/mzscheme/benchmarks/common/earley.sch new file mode 100644 index 0000000000..da885155e5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/earley.sch @@ -0,0 +1,650 @@ +;;; EARLEY -- Earley's parser, written by Marc Feeley. + +; $Id: earley.sch,v 1.2 1999/07/12 18:05:19 lth Exp $ +; 990708 / lth -- changed 'main' to 'earley-benchmark'. +; +; (make-parser grammar lexer) is used to create a parser from the grammar +; description `grammar' and the lexer function `lexer'. +; +; A grammar is a list of definitions. Each definition defines a non-terminal +; by a set of rules. Thus a definition has the form: (nt rule1 rule2...). +; A given non-terminal can only be defined once. The first non-terminal +; defined is the grammar's goal. Each rule is a possibly empty list of +; non-terminals. Thus a rule has the form: (nt1 nt2...). A non-terminal +; can be any scheme value. Note that all grammar symbols are treated as +; non-terminals. This is fine though because the lexer will be outputing +; non-terminals. +; +; The lexer defines what a token is and the mapping between tokens and +; the grammar's non-terminals. It is a function of one argument, the input, +; that returns the list of tokens corresponding to the input. Each token is +; represented by a list. The first element is some `user-defined' information +; associated with the token and the rest represents the token's class(es) (as a +; list of non-terminals that this token corresponds to). +; +; The result of `make-parser' is a function that parses the single input it +; is given into the grammar's goal. The result is a `parse' which can be +; manipulated with the procedures: `parse->parsed?', `parse->trees' +; and `parse->nb-trees' (see below). +; +; Let's assume that we want a parser for the grammar +; +; S -> x = E +; E -> E + E | V +; V -> V y | +; +; and that the input to the parser is a string of characters. Also, assume we +; would like to map the characters `x', `y', `+' and `=' into the corresponding +; non-terminals in the grammar. Such a parser could be created with +; +; (make-parser +; '( +; (s (x = e)) +; (e (e + e) (v)) +; (v (v y) ()) +; ) +; (lambda (str) +; (map (lambda (char) +; (list char ; user-info = the character itself +; (case char +; ((#\x) 'x) +; ((#\y) 'y) +; ((#\+) '+) +; ((#\=) '=) +; (else (fatal-error "lexer error"))))) +; (string->list str))) +; ) +; +; An alternative definition (that does not check for lexical errors) is +; +; (make-parser +; '( +; (s (#\x #\= e)) +; (e (e #\+ e) (v)) +; (v (v #\y) ()) +; ) +; (lambda (str) (map (lambda (char) (list char char)) (string->list str))) +; ) +; +; To help with the rest of the discussion, here are a few definitions: +; +; An input pointer (for an input of `n' tokens) is a value between 0 and `n'. +; It indicates a point between two input tokens (0 = beginning, `n' = end). +; For example, if `n' = 4, there are 5 input pointers: +; +; input token1 token2 token3 token4 +; input pointers 0 1 2 3 4 +; +; A configuration indicates the extent to which a given rule is parsed (this +; is the common `dot notation'). For simplicity, a configuration is +; represented as an integer, with successive configurations in the same +; rule associated with successive integers. It is assumed that the grammar +; has been extended with rules to aid scanning. These rules are of the +; form `nt ->', and there is one such rule for every non-terminal. Note +; that these rules are special because they only apply when the corresponding +; non-terminal is returned by the lexer. +; +; A configuration set is a configuration grouped with the set of input pointers +; representing where the head non-terminal of the configuration was predicted. +; +; Here are the rules and configurations for the grammar given above: +; +; S -> . \ +; 0 | +; x -> . | +; 1 | +; = -> . | +; 2 | +; E -> . | +; 3 > special rules (for scanning) +; + -> . | +; 4 | +; V -> . | +; 5 | +; y -> . | +; 6 / +; S -> . x . = . E . +; 7 8 9 10 +; E -> . E . + . E . +; 11 12 13 14 +; E -> . V . +; 15 16 +; V -> . V . y . +; 17 18 19 +; V -> . +; 20 +; +; Starters of the non-terminal `nt' are configurations that are leftmost +; in a non-special rule for `nt'. Enders of the non-terminal `nt' are +; configurations that are rightmost in any rule for `nt'. Predictors of the +; non-terminal `nt' are configurations that are directly to the left of `nt' +; in any rule. +; +; For the grammar given above, +; +; Starters of V = (17 20) +; Enders of V = (5 19 20) +; Predictors of V = (15 17) + +(define (make-parser grammar lexer) + + (define (non-terminals grammar) ; return vector of non-terminals in grammar + + (define (add-nt nt nts) + (if (member nt nts) nts (cons nt nts))) ; use equal? for equality tests + + (let def-loop ((defs grammar) (nts '())) + (if (pair? defs) + (let* ((def (car defs)) + (head (car def))) + (let rule-loop ((rules (cdr def)) + (nts (add-nt head nts))) + (if (pair? rules) + (let ((rule (car rules))) + (let loop ((l rule) (nts nts)) + (if (pair? l) + (let ((nt (car l))) + (loop (cdr l) (add-nt nt nts))) + (rule-loop (cdr rules) nts)))) + (def-loop (cdr defs) nts)))) + (list->vector (reverse nts))))) ; goal non-terminal must be at index 0 + + (define (ind nt nts) ; return index of non-terminal `nt' in `nts' + (let loop ((i (- (vector-length nts) 1))) + (if (>= i 0) + (if (equal? (vector-ref nts i) nt) i (loop (- i 1))) + #f))) + + (define (nb-configurations grammar) ; return nb of configurations in grammar + (let def-loop ((defs grammar) (nb-confs 0)) + (if (pair? defs) + (let ((def (car defs))) + (let rule-loop ((rules (cdr def)) (nb-confs nb-confs)) + (if (pair? rules) + (let ((rule (car rules))) + (let loop ((l rule) (nb-confs nb-confs)) + (if (pair? l) + (loop (cdr l) (+ nb-confs 1)) + (rule-loop (cdr rules) (+ nb-confs 1))))) + (def-loop (cdr defs) nb-confs)))) + nb-confs))) + +; First, associate a numeric identifier to every non-terminal in the +; grammar (with the goal non-terminal associated with 0). +; +; So, for the grammar given above we get: +; +; s -> 0 x -> 1 = -> 4 e ->3 + -> 4 v -> 5 y -> 6 + + (let* ((nts (non-terminals grammar)) ; id map = list of non-terms + (nb-nts (vector-length nts)) ; the number of non-terms + (nb-confs (+ (nb-configurations grammar) nb-nts)) ; the nb of confs + (starters (make-vector nb-nts '())) ; starters for every non-term + (enders (make-vector nb-nts '())) ; enders for every non-term + (predictors (make-vector nb-nts '())) ; predictors for every non-term + (steps (make-vector nb-confs #f)) ; what to do in a given conf + (names (make-vector nb-confs #f))) ; name of rules + + (define (setup-tables grammar nts starters enders predictors steps names) + + (define (add-conf conf nt nts class) + (let ((i (ind nt nts))) + (vector-set! class i (cons conf (vector-ref class i))))) + + (let ((nb-nts (vector-length nts))) + + (let nt-loop ((i (- nb-nts 1))) + (if (>= i 0) + (begin + (vector-set! steps i (- i nb-nts)) + (vector-set! names i (list (vector-ref nts i) 0)) + (vector-set! enders i (list i)) + (nt-loop (- i 1))))) + + (let def-loop ((defs grammar) (conf (vector-length nts))) + (if (pair? defs) + (let* ((def (car defs)) + (head (car def))) + (let rule-loop ((rules (cdr def)) (conf conf) (rule-num 1)) + (if (pair? rules) + (let ((rule (car rules))) + (vector-set! names conf (list head rule-num)) + (add-conf conf head nts starters) + (let loop ((l rule) (conf conf)) + (if (pair? l) + (let ((nt (car l))) + (vector-set! steps conf (ind nt nts)) + (add-conf conf nt nts predictors) + (loop (cdr l) (+ conf 1))) + (begin + (vector-set! steps conf (- (ind head nts) nb-nts)) + (add-conf conf head nts enders) + (rule-loop (cdr rules) (+ conf 1) (+ rule-num 1)))))) + (def-loop (cdr defs) conf)))))))) + +; Now, for each non-terminal, compute the starters, enders and predictors and +; the names and steps tables. + + (setup-tables grammar nts starters enders predictors steps names) + +; Build the parser description + + (let ((parser-descr (vector lexer + nts + starters + enders + predictors + steps + names))) + (lambda (input) + + (define (ind nt nts) ; return index of non-terminal `nt' in `nts' + (let loop ((i (- (vector-length nts) 1))) + (if (>= i 0) + (if (equal? (vector-ref nts i) nt) i (loop (- i 1))) + #f))) + + (define (comp-tok tok nts) ; transform token to parsing format + (let loop ((l1 (cdr tok)) (l2 '())) + (if (pair? l1) + (let ((i (ind (car l1) nts))) + (if i + (loop (cdr l1) (cons i l2)) + (loop (cdr l1) l2))) + (cons (car tok) (reverse l2))))) + + (define (input->tokens input lexer nts) + (list->vector (map (lambda (tok) (comp-tok tok nts)) (lexer input)))) + + (define (make-states nb-toks nb-confs) + (let ((states (make-vector (+ nb-toks 1) #f))) + (let loop ((i nb-toks)) + (if (>= i 0) + (let ((v (make-vector (+ nb-confs 1) #f))) + (vector-set! v 0 -1) + (vector-set! states i v) + (loop (- i 1))) + states)))) + + (define (conf-set-get state conf) + (vector-ref state (+ conf 1))) + + (define (conf-set-get* state state-num conf) + (let ((conf-set (conf-set-get state conf))) + (if conf-set + conf-set + (let ((conf-set (make-vector (+ state-num 6) #f))) + (vector-set! conf-set 1 -3) ; old elems tail (points to head) + (vector-set! conf-set 2 -1) ; old elems head + (vector-set! conf-set 3 -1) ; new elems tail (points to head) + (vector-set! conf-set 4 -1) ; new elems head + (vector-set! state (+ conf 1) conf-set) + conf-set)))) + + (define (conf-set-merge-new! conf-set) + (vector-set! conf-set + (+ (vector-ref conf-set 1) 5) + (vector-ref conf-set 4)) + (vector-set! conf-set 1 (vector-ref conf-set 3)) + (vector-set! conf-set 3 -1) + (vector-set! conf-set 4 -1)) + + (define (conf-set-head conf-set) + (vector-ref conf-set 2)) + + (define (conf-set-next conf-set i) + (vector-ref conf-set (+ i 5))) + + (define (conf-set-member? state conf i) + (let ((conf-set (vector-ref state (+ conf 1)))) + (if conf-set + (conf-set-next conf-set i) + #f))) + + (define (conf-set-adjoin state conf-set conf i) + (let ((tail (vector-ref conf-set 3))) ; put new element at tail + (vector-set! conf-set (+ i 5) -1) + (vector-set! conf-set (+ tail 5) i) + (vector-set! conf-set 3 i) + (if (< tail 0) + (begin + (vector-set! conf-set 0 (vector-ref state 0)) + (vector-set! state 0 conf))))) + + (define (conf-set-adjoin* states state-num l i) + (let ((state (vector-ref states state-num))) + (let loop ((l1 l)) + (if (pair? l1) + (let* ((conf (car l1)) + (conf-set (conf-set-get* state state-num conf))) + (if (not (conf-set-next conf-set i)) + (begin + (conf-set-adjoin state conf-set conf i) + (loop (cdr l1))) + (loop (cdr l1)))))))) + + (define (conf-set-adjoin** states states* state-num conf i) + (let ((state (vector-ref states state-num))) + (if (conf-set-member? state conf i) + (let* ((state* (vector-ref states* state-num)) + (conf-set* (conf-set-get* state* state-num conf))) + (if (not (conf-set-next conf-set* i)) + (conf-set-adjoin state* conf-set* conf i)) + #t) + #f))) + + (define (conf-set-union state conf-set conf other-set) + (let loop ((i (conf-set-head other-set))) + (if (>= i 0) + (if (not (conf-set-next conf-set i)) + (begin + (conf-set-adjoin state conf-set conf i) + (loop (conf-set-next other-set i))) + (loop (conf-set-next other-set i)))))) + + (define (forw states state-num starters enders predictors steps nts) + + (define (predict state state-num conf-set conf nt starters enders) + + ; add configurations which start the non-terminal `nt' to the + ; right of the dot + + (let loop1 ((l (vector-ref starters nt))) + (if (pair? l) + (let* ((starter (car l)) + (starter-set (conf-set-get* state state-num starter))) + (if (not (conf-set-next starter-set state-num)) + (begin + (conf-set-adjoin state starter-set starter state-num) + (loop1 (cdr l))) + (loop1 (cdr l)))))) + + ; check for possible completion of the non-terminal `nt' to the + ; right of the dot + + (let loop2 ((l (vector-ref enders nt))) + (if (pair? l) + (let ((ender (car l))) + (if (conf-set-member? state ender state-num) + (let* ((next (+ conf 1)) + (next-set (conf-set-get* state state-num next))) + (conf-set-union state next-set next conf-set) + (loop2 (cdr l))) + (loop2 (cdr l))))))) + + (define (reduce states state state-num conf-set head preds) + + ; a non-terminal is now completed so check for reductions that + ; are now possible at the configurations `preds' + + (let loop1 ((l preds)) + (if (pair? l) + (let ((pred (car l))) + (let loop2 ((i head)) + (if (>= i 0) + (let ((pred-set (conf-set-get (vector-ref states i) pred))) + (if pred-set + (let* ((next (+ pred 1)) + (next-set (conf-set-get* state state-num next))) + (conf-set-union state next-set next pred-set))) + (loop2 (conf-set-next conf-set i))) + (loop1 (cdr l)))))))) + + (let ((state (vector-ref states state-num)) + (nb-nts (vector-length nts))) + (let loop () + (let ((conf (vector-ref state 0))) + (if (>= conf 0) + (let* ((step (vector-ref steps conf)) + (conf-set (vector-ref state (+ conf 1))) + (head (vector-ref conf-set 4))) + (vector-set! state 0 (vector-ref conf-set 0)) + (conf-set-merge-new! conf-set) + (if (>= step 0) + (predict state state-num conf-set conf step starters enders) + (let ((preds (vector-ref predictors (+ step nb-nts)))) + (reduce states state state-num conf-set head preds))) + (loop))))))) + + (define (forward starters enders predictors steps nts toks) + (let* ((nb-toks (vector-length toks)) + (nb-confs (vector-length steps)) + (states (make-states nb-toks nb-confs)) + (goal-starters (vector-ref starters 0))) + (conf-set-adjoin* states 0 goal-starters 0) ; predict goal + (forw states 0 starters enders predictors steps nts) + (let loop ((i 0)) + (if (< i nb-toks) + (let ((tok-nts (cdr (vector-ref toks i)))) + (conf-set-adjoin* states (+ i 1) tok-nts i) ; scan token + (forw states (+ i 1) starters enders predictors steps nts) + (loop (+ i 1))))) + states)) + + (define (produce conf i j enders steps toks states states* nb-nts) + (let ((prev (- conf 1))) + (if (and (>= conf nb-nts) (>= (vector-ref steps prev) 0)) + (let loop1 ((l (vector-ref enders (vector-ref steps prev)))) + (if (pair? l) + (let* ((ender (car l)) + (ender-set (conf-set-get (vector-ref states j) + ender))) + (if ender-set + (let loop2 ((k (conf-set-head ender-set))) + (if (>= k 0) + (begin + (and (>= k i) + (conf-set-adjoin** states states* k prev i) + (conf-set-adjoin** states states* j ender k)) + (loop2 (conf-set-next ender-set k))) + (loop1 (cdr l)))) + (loop1 (cdr l))))))))) + + (define (back states states* state-num enders steps nb-nts toks) + (let ((state* (vector-ref states* state-num))) + (let loop1 () + (let ((conf (vector-ref state* 0))) + (if (>= conf 0) + (let* ((conf-set (vector-ref state* (+ conf 1))) + (head (vector-ref conf-set 4))) + (vector-set! state* 0 (vector-ref conf-set 0)) + (conf-set-merge-new! conf-set) + (let loop2 ((i head)) + (if (>= i 0) + (begin + (produce conf i state-num enders steps + toks states states* nb-nts) + (loop2 (conf-set-next conf-set i))) + (loop1))))))))) + + (define (backward states enders steps nts toks) + (let* ((nb-toks (vector-length toks)) + (nb-confs (vector-length steps)) + (nb-nts (vector-length nts)) + (states* (make-states nb-toks nb-confs)) + (goal-enders (vector-ref enders 0))) + (let loop1 ((l goal-enders)) + (if (pair? l) + (let ((conf (car l))) + (conf-set-adjoin** states states* nb-toks conf 0) + (loop1 (cdr l))))) + (let loop2 ((i nb-toks)) + (if (>= i 0) + (begin + (back states states* i enders steps nb-nts toks) + (loop2 (- i 1))))) + states*)) + + (define (parsed? nt i j nts enders states) + (let ((nt* (ind nt nts))) + (if nt* + (let ((nb-nts (vector-length nts))) + (let loop ((l (vector-ref enders nt*))) + (if (pair? l) + (let ((conf (car l))) + (if (conf-set-member? (vector-ref states j) conf i) + #t + (loop (cdr l)))) + #f))) + #f))) + + (define (deriv-trees conf i j enders steps names toks states nb-nts) + (let ((name (vector-ref names conf))) + + (if name ; `conf' is at the start of a rule (either special or not) + (if (< conf nb-nts) + (list (list name (car (vector-ref toks i)))) + (list (list name))) + + (let ((prev (- conf 1))) + (let loop1 ((l1 (vector-ref enders (vector-ref steps prev))) + (l2 '())) + (if (pair? l1) + (let* ((ender (car l1)) + (ender-set (conf-set-get (vector-ref states j) + ender))) + (if ender-set + (let loop2 ((k (conf-set-head ender-set)) (l2 l2)) + (if (>= k 0) + (if (and (>= k i) + (conf-set-member? (vector-ref states k) + prev i)) + (let ((prev-trees + (deriv-trees prev i k enders steps names + toks states nb-nts)) + (ender-trees + (deriv-trees ender k j enders steps names + toks states nb-nts))) + (let loop3 ((l3 ender-trees) (l2 l2)) + (if (pair? l3) + (let ((ender-tree (list (car l3)))) + (let loop4 ((l4 prev-trees) (l2 l2)) + (if (pair? l4) + (loop4 (cdr l4) + (cons (append (car l4) + ender-tree) + l2)) + (loop3 (cdr l3) l2)))) + (loop2 (conf-set-next ender-set k) l2)))) + (loop2 (conf-set-next ender-set k) l2)) + (loop1 (cdr l1) l2))) + (loop1 (cdr l1) l2))) + l2)))))) + + (define (deriv-trees* nt i j nts enders steps names toks states) + (let ((nt* (ind nt nts))) + (if nt* + (let ((nb-nts (vector-length nts))) + (let loop ((l (vector-ref enders nt*)) (trees '())) + (if (pair? l) + (let ((conf (car l))) + (if (conf-set-member? (vector-ref states j) conf i) + (loop (cdr l) + (append (deriv-trees conf i j enders steps names + toks states nb-nts) + trees)) + (loop (cdr l) trees))) + trees))) + #f))) + + (define (nb-deriv-trees conf i j enders steps toks states nb-nts) + (let ((prev (- conf 1))) + (if (or (< conf nb-nts) (< (vector-ref steps prev) 0)) + 1 + (let loop1 ((l (vector-ref enders (vector-ref steps prev))) + (n 0)) + (if (pair? l) + (let* ((ender (car l)) + (ender-set (conf-set-get (vector-ref states j) + ender))) + (if ender-set + (let loop2 ((k (conf-set-head ender-set)) (n n)) + (if (>= k 0) + (if (and (>= k i) + (conf-set-member? (vector-ref states k) + prev i)) + (let ((nb-prev-trees + (nb-deriv-trees prev i k enders steps + toks states nb-nts)) + (nb-ender-trees + (nb-deriv-trees ender k j enders steps + toks states nb-nts))) + (loop2 (conf-set-next ender-set k) + (+ n (* nb-prev-trees nb-ender-trees)))) + (loop2 (conf-set-next ender-set k) n)) + (loop1 (cdr l) n))) + (loop1 (cdr l) n))) + n))))) + + (define (nb-deriv-trees* nt i j nts enders steps toks states) + (let ((nt* (ind nt nts))) + (if nt* + (let ((nb-nts (vector-length nts))) + (let loop ((l (vector-ref enders nt*)) (nb-trees 0)) + (if (pair? l) + (let ((conf (car l))) + (if (conf-set-member? (vector-ref states j) conf i) + (loop (cdr l) + (+ (nb-deriv-trees conf i j enders steps + toks states nb-nts) + nb-trees)) + (loop (cdr l) nb-trees))) + nb-trees))) + #f))) + + (let* ((lexer (vector-ref parser-descr 0)) + (nts (vector-ref parser-descr 1)) + (starters (vector-ref parser-descr 2)) + (enders (vector-ref parser-descr 3)) + (predictors (vector-ref parser-descr 4)) + (steps (vector-ref parser-descr 5)) + (names (vector-ref parser-descr 6)) + (toks (input->tokens input lexer nts))) + + (vector nts + starters + enders + predictors + steps + names + toks + (backward (forward starters enders predictors steps nts toks) + enders steps nts toks) + parsed? + deriv-trees* + nb-deriv-trees*)))))) + +(define (parse->parsed? parse nt i j) + (let* ((nts (vector-ref parse 0)) + (enders (vector-ref parse 2)) + (states (vector-ref parse 7)) + (parsed? (vector-ref parse 8))) + (parsed? nt i j nts enders states))) + +(define (parse->trees parse nt i j) + (let* ((nts (vector-ref parse 0)) + (enders (vector-ref parse 2)) + (steps (vector-ref parse 4)) + (names (vector-ref parse 5)) + (toks (vector-ref parse 6)) + (states (vector-ref parse 7)) + (deriv-trees* (vector-ref parse 9))) + (deriv-trees* nt i j nts enders steps names toks states))) + +(define (parse->nb-trees parse nt i j) + (let* ((nts (vector-ref parse 0)) + (enders (vector-ref parse 2)) + (steps (vector-ref parse 4)) + (toks (vector-ref parse 6)) + (states (vector-ref parse 7)) + (nb-deriv-trees* (vector-ref parse 10))) + (nb-deriv-trees* nt i j nts enders steps toks states))) + +(define (test k) + (let ((p (make-parser '( (s (a) (s s)) ) + (lambda (l) (map (lambda (x) (list x x)) l))))) + (let ((x (p (vector->list (make-vector k 'a))))) + (length (parse->trees x 's 0 k))))) + +(time (test 12)) + diff --git a/collects/tests/mzscheme/benchmarks/common/earley.ss b/collects/tests/mzscheme/benchmarks/common/earley.ss new file mode 100644 index 0000000000..8033ac2250 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/earley.ss @@ -0,0 +1,2 @@ + +(module earley "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/fft.sch b/collects/tests/mzscheme/benchmarks/common/fft.sch new file mode 100644 index 0000000000..92ed55d0e1 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/fft.sch @@ -0,0 +1,117 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: fft.cl +; Description: FFT benchmark from the Gabriel tests. +; Author: Harry Barrow +; Created: 8-Apr-85 +; Modified: 6-May-85 09:29:22 (Bob Shaw) +; 11-Aug-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define pi (atan 0 -1)) + +;;; FFT -- This is an FFT benchmark written by Harry Barrow. +;;; It tests a variety of floating point operations, +;;; including array references. + +(define *re* (make-vector 1025 0.0)) + +(define *im* (make-vector 1025 0.0)) + +(define (fft areal aimag) + (let ((ar 0) + (ai 0) + (i 0) + (j 0) + (k 0) + (m 0) + (n 0) + (le 0) + (le1 0) + (ip 0) + (nv2 0) + (nm1 0) + (ur 0) + (ui 0) + (wr 0) + (wi 0) + (tr 0) + (ti 0)) + ;; initialize + (set! ar areal) + (set! ai aimag) + (set! n (vector-length ar)) + (set! n (- n 1)) + (set! nv2 (quotient n 2)) + (set! nm1 (- n 1)) + (set! m 0) ;compute m = log(n) + (set! i 1) + (let loop () + (if (< i n) + (begin (set! m (+ m 1)) + (set! i (+ i i)) + (loop)))) + (cond ((not (= n (expt 2 m))) + (error "array size not a power of two."))) + ;; interchange elements in bit-reversed order + (set! j 1) + (set! i 1) + (let l3 () + (cond ((< i j) + (set! tr (vector-ref ar j)) + (set! ti (vector-ref ai j)) + (vector-set! ar j (vector-ref ar i)) + (vector-set! ai j (vector-ref ai i)) + (vector-set! ar i tr) + (vector-set! ai i ti))) + (set! k nv2) + (let l6 () + (cond ((< k j) + (set! j (- j k)) + (set! k (/ k 2)) + (l6)))) + (set! j (+ j k)) + (set! i (+ i 1)) + (cond ((< i n) + (l3)))) + (do ((l 1 (+ l 1))) ;loop thru stages (syntax converted + ((> l m)) ; from old MACLISP style \bs) + (set! le (expt 2 l)) + (set! le1 (quotient le 2)) + (set! ur 1.0) + (set! ui 0.) + (set! wr (cos (/ pi le1))) + (set! wi (sin (/ pi le1))) + ;; loop thru butterflies + (do ((j 1 (+ j 1))) + ((> j le1)) + ;; do a butterfly + (do ((i j (+ i le))) + ((> i n)) + (set! ip (+ i le1)) + (set! tr (- (* (vector-ref ar ip) ur) + (* (vector-ref ai ip) ui))) + (set! ti (+ (* (vector-ref ar ip) ui) + (* (vector-ref ai ip) ur))) + (vector-set! ar ip (- (vector-ref ar i) tr)) + (vector-set! ai ip (- (vector-ref ai i) ti)) + (vector-set! ar i (+ (vector-ref ar i) tr)) + (vector-set! ai i (+ (vector-ref ai i) ti)))) + (set! tr (- (* ur wr) (* ui wi))) + (set! ti (+ (* ur wi) (* ui wr))) + (set! ur tr) + (set! ui ti)) + #t)) + +;;; the timer which does 10 calls on fft + +(define (fft-bench) + (do ((ntimes 0 (+ ntimes 1))) + ((= ntimes 1000)) + (fft *re* *im*))) + +;;; call: (fft-bench) + +(time (fft-bench)) + diff --git a/collects/tests/mzscheme/benchmarks/common/fft.ss b/collects/tests/mzscheme/benchmarks/common/fft.ss new file mode 100644 index 0000000000..ed81fa0266 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/fft.ss @@ -0,0 +1,2 @@ + +(module fft "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/graphs.sch b/collects/tests/mzscheme/benchmarks/common/graphs.sch new file mode 100644 index 0000000000..1a114eacc2 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/graphs.sch @@ -0,0 +1,645 @@ +; Modified 2 March 1997 by Will Clinger to add graphs-benchmark +; and to expand the four macros below. +; Modified 11 June 1997 by Will Clinger to eliminate assertions +; and to replace a use of "recur" with a named let. +; +; Performance note: (graphs-benchmark 7) allocates +; 34509143 pairs +; 389625 vectors with 2551590 elements +; 56653504 closures (not counting top level and known procedures) + +(define (graphs-benchmark . rest) + (let ((N (if (null? rest) 7 (car rest)))) + (time + (fold-over-rdg N + 2 + cons + '())))) + +; End of new code. + +;;; ==== std.ss ==== + +; (define-syntax assert +; (syntax-rules () +; ((assert test info-rest ...) +; #F))) +; +; (define-syntax deny +; (syntax-rules () +; ((deny test info-rest ...) +; #F))) +; +; (define-syntax when +; (syntax-rules () +; ((when test e-first e-rest ...) +; (if test +; (begin e-first +; e-rest ...))))) +; +; (define-syntax unless +; (syntax-rules () +; ((unless test e-first e-rest ...) +; (if (not test) +; (begin e-first +; e-rest ...))))) + +(define assert + (lambda (test . info) + #f)) + +;;; ==== util.ss ==== + + +; Fold over list elements, associating to the left. +(define fold + (lambda (lst folder state) + '(assert (list? lst) + lst) + '(assert (procedure? folder) + folder) + (do ((lst lst + (cdr lst)) + (state state + (folder (car lst) + state))) + ((null? lst) + state)))) + +; Given the size of a vector and a procedure which +; sends indicies to desired vector elements, create +; and return the vector. +(define proc->vector + (lambda (size f) + '(assert (and (integer? size) + (exact? size) + (>= size 0)) + size) + '(assert (procedure? f) + f) + (if (zero? size) + (vector) + (let ((x (make-vector size (f 0)))) + (let loop ((i 1)) + (if (< i size) (begin ; [wdc - was when] + (vector-set! x i (f i)) + (loop (+ i 1))))) + x)))) + +(define vector-fold + (lambda (vec folder state) + '(assert (vector? vec) + vec) + '(assert (procedure? folder) + folder) + (let ((len + (vector-length vec))) + (do ((i 0 + (+ i 1)) + (state state + (folder (vector-ref vec i) + state))) + ((= i len) + state))))) + +(define vector-map + (lambda (vec proc) + (proc->vector (vector-length vec) + (lambda (i) + (proc (vector-ref vec i)))))) + +; Given limit, return the list 0, 1, ..., limit-1. +(define giota + (lambda (limit) + '(assert (and (integer? limit) + (exact? limit) + (>= limit 0)) + limit) + (let -*- + ((limit + limit) + (res + '())) + (if (zero? limit) + res + (let ((limit + (- limit 1))) + (-*- limit + (cons limit res))))))) + +; Fold over the integers [0, limit). +(define gnatural-fold + (lambda (limit folder state) + '(assert (and (integer? limit) + (exact? limit) + (>= limit 0)) + limit) + '(assert (procedure? folder) + folder) + (do ((i 0 + (+ i 1)) + (state state + (folder i state))) + ((= i limit) + state)))) + +; Iterate over the integers [0, limit). +(define gnatural-for-each + (lambda (limit proc!) + '(assert (and (integer? limit) + (exact? limit) + (>= limit 0)) + limit) + '(assert (procedure? proc!) + proc!) + (do ((i 0 + (+ i 1))) + ((= i limit)) + (proc! i)))) + +(define natural-for-all? + (lambda (limit ok?) + '(assert (and (integer? limit) + (exact? limit) + (>= limit 0)) + limit) + '(assert (procedure? ok?) + ok?) + (let -*- + ((i 0)) + (or (= i limit) + (and (ok? i) + (-*- (+ i 1))))))) + +(define natural-there-exists? + (lambda (limit ok?) + '(assert (and (integer? limit) + (exact? limit) + (>= limit 0)) + limit) + '(assert (procedure? ok?) + ok?) + (let -*- + ((i 0)) + (and (not (= i limit)) + (or (ok? i) + (-*- (+ i 1))))))) + +(define there-exists? + (lambda (lst ok?) + '(assert (list? lst) + lst) + '(assert (procedure? ok?) + ok?) + (let -*- + ((lst lst)) + (and (not (null? lst)) + (or (ok? (car lst)) + (-*- (cdr lst))))))) + + +;;; ==== ptfold.ss ==== + + +; Fold over the tree of permutations of a universe. +; Each branch (from the root) is a permutation of universe. +; Each node at depth d corresponds to all permutations which pick the +; elements spelled out on the branch from the root to that node as +; the first d elements. +; Their are two components to the state: +; The b-state is only a function of the branch from the root. +; The t-state is a function of all nodes seen so far. +; At each node, b-folder is called via +; (b-folder elem b-state t-state deeper accross) +; where elem is the next element of the universe picked. +; If b-folder can determine the result of the total tree fold at this stage, +; it should simply return the result. +; If b-folder can determine the result of folding over the sub-tree +; rooted at the resulting node, it should call accross via +; (accross new-t-state) +; where new-t-state is that result. +; Otherwise, b-folder should call deeper via +; (deeper new-b-state new-t-state) +; where new-b-state is the b-state for the new node and new-t-state is +; the new folded t-state. +; At the leaves of the tree, t-folder is called via +; (t-folder b-state t-state accross) +; If t-folder can determine the result of the total tree fold at this stage, +; it should simply return that result. +; If not, it should call accross via +; (accross new-t-state) +; Note, fold-over-perm-tree always calls b-folder in depth-first order. +; I.e., when b-folder is called at depth d, the branch leading to that +; node is the most recent calls to b-folder at all the depths less than d. +; This is a gross efficiency hack so that b-folder can use mutation to +; keep the current branch. +(define fold-over-perm-tree + (lambda (universe b-folder b-state t-folder t-state) + '(assert (list? universe) + universe) + '(assert (procedure? b-folder) + b-folder) + '(assert (procedure? t-folder) + t-folder) + (let -*- + ((universe + universe) + (b-state + b-state) + (t-state + t-state) + (accross + (lambda (final-t-state) + final-t-state))) + (if (null? universe) + (t-folder b-state t-state accross) + (let -**- + ((in + universe) + (out + '()) + (t-state + t-state)) + (let* ((first + (car in)) + (rest + (cdr in)) + (accross + (if (null? rest) + accross + (lambda (new-t-state) + (-**- rest + (cons first out) + new-t-state))))) + (b-folder first + b-state + t-state + (lambda (new-b-state new-t-state) + (-*- (fold out cons rest) + new-b-state + new-t-state + accross)) + accross))))))) + + +;;; ==== minimal.ss ==== + + +; A directed graph is stored as a connection matrix (vector-of-vectors) +; where the first index is the `from' vertex and the second is the `to' +; vertex. Each entry is a bool indicating if the edge exists. +; The diagonal of the matrix is never examined. +; Make-minimal? returns a procedure which tests if a labelling +; of the verticies is such that the matrix is minimal. +; If it is, then the procedure returns the result of folding over +; the elements of the automoriphism group. If not, it returns #F. +; The folding is done by calling folder via +; (folder perm state accross) +; If the folder wants to continue, it should call accross via +; (accross new-state) +; If it just wants the entire minimal? procedure to return something, +; it should return that. +; The ordering used is lexicographic (with #T > #F) and entries +; are examined in the following order: +; 1->0, 0->1 +; +; 2->0, 0->2 +; 2->1, 1->2 +; +; 3->0, 0->3 +; 3->1, 1->3 +; 3->2, 2->3 +; ... +(define make-minimal? + (lambda (max-size) + '(assert (and (integer? max-size) + (exact? max-size) + (>= max-size 0)) + max-size) + (let ((iotas + (proc->vector (+ max-size 1) + giota)) + (perm + (make-vector max-size 0))) + (lambda (size graph folder state) + '(assert (and (integer? size) + (exact? size) + (<= 0 size max-size)) + size + max-size) + '(assert (vector? graph) + graph) + '(assert (procedure? folder) + folder) + (fold-over-perm-tree (vector-ref iotas size) + (lambda (perm-x x state deeper accross) + (case (cmp-next-vertex graph perm x perm-x) + ((less) + #F) + ((equal) + (vector-set! perm x perm-x) + (deeper (+ x 1) + state)) + ((more) + (accross state)) + (else + (assert #F)))) + 0 + (lambda (leaf-depth state accross) + '(assert (eqv? leaf-depth size) + leaf-depth + size) + (folder perm state accross)) + state))))) + +; Given a graph, a partial permutation vector, the next input and the next +; output, return 'less, 'equal or 'more depending on the lexicographic +; comparison between the permuted and un-permuted graph. +(define cmp-next-vertex + (lambda (graph perm x perm-x) + (let ((from-x + (vector-ref graph x)) + (from-perm-x + (vector-ref graph perm-x))) + (let -*- + ((y + 0)) + (if (= x y) + 'equal + (let ((x->y? + (vector-ref from-x y)) + (perm-y + (vector-ref perm y))) + (cond ((eq? x->y? + (vector-ref from-perm-x perm-y)) + (let ((y->x? + (vector-ref (vector-ref graph y) + x))) + (cond ((eq? y->x? + (vector-ref (vector-ref graph perm-y) + perm-x)) + (-*- (+ y 1))) + (y->x? + 'less) + (else + 'more)))) + (x->y? + 'less) + (else + 'more)))))))) + + +;;; ==== rdg.ss ==== + + +; Fold over rooted directed graphs with bounded out-degree. +; Size is the number of verticies (including the root). Max-out is the +; maximum out-degree for any vertex. Folder is called via +; (folder edges state) +; where edges is a list of length size. The ith element of the list is +; a list of the verticies j for which there is an edge from i to j. +; The last vertex is the root. +(define fold-over-rdg + (lambda (size max-out folder state) + '(assert (and (exact? size) + (integer? size) + (> size 0)) + size) + '(assert (and (exact? max-out) + (integer? max-out) + (>= max-out 0)) + max-out) + '(assert (procedure? folder) + folder) + (let* ((root + (- size 1)) + (edge? + (proc->vector size + (lambda (from) + (make-vector size #F)))) + (edges + (make-vector size '())) + (out-degrees + (make-vector size 0)) + (minimal-folder + (make-minimal? root)) + (non-root-minimal? + (let ((cont + (lambda (perm state accross) + '(assert (eq? state #T) + state) + (accross #T)))) + (lambda (size) + (minimal-folder size + edge? + cont + #T)))) + (root-minimal? + (let ((cont + (lambda (perm state accross) + '(assert (eq? state #T) + state) + (case (cmp-next-vertex edge? perm root root) + ((less) + #F) + ((equal more) + (accross #T)) + (else + (assert #F)))))) + (lambda () + (minimal-folder root + edge? + cont + #T))))) + (let -*- + ((vertex + 0) + (state + state)) + (cond ((not (non-root-minimal? vertex)) + state) + ((= vertex root) + '(assert + (begin + (gnatural-for-each root + (lambda (v) + '(assert (= (vector-ref out-degrees v) + (length (vector-ref edges v))) + v + (vector-ref out-degrees v) + (vector-ref edges v)))) + #T)) + (let ((reach? + (make-reach? root edges)) + (from-root + (vector-ref edge? root))) + (let -*- + ((v + 0) + (outs + 0) + (efr + '()) + (efrr + '()) + (state + state)) + (cond ((not (or (= v root) + (= outs max-out))) + (vector-set! from-root v #T) + (let ((state + (-*- (+ v 1) + (+ outs 1) + (cons v efr) + (cons (vector-ref reach? v) + efrr) + state))) + (vector-set! from-root v #F) + (-*- (+ v 1) + outs + efr + efrr + state))) + ((and (natural-for-all? root + (lambda (v) + (there-exists? efrr + (lambda (r) + (vector-ref r v))))) + (root-minimal?)) + (vector-set! edges root efr) + (folder + (proc->vector size + (lambda (i) + (vector-ref edges i))) + state)) + (else + state))))) + (else + (let ((from-vertex + (vector-ref edge? vertex))) + (let -**- + ((sv + 0) + (outs + 0) + (state + state)) + (if (= sv vertex) + (begin + (vector-set! out-degrees vertex outs) + (-*- (+ vertex 1) + state)) + (let* ((state + ; no sv->vertex, no vertex->sv + (-**- (+ sv 1) + outs + state)) + (from-sv + (vector-ref edge? sv)) + (sv-out + (vector-ref out-degrees sv)) + (state + (if (= sv-out max-out) + state + (begin + (vector-set! edges + sv + (cons vertex + (vector-ref edges sv))) + (vector-set! from-sv vertex #T) + (vector-set! out-degrees sv (+ sv-out 1)) + (let* ((state + ; sv->vertex, no vertex->sv + (-**- (+ sv 1) + outs + state)) + (state + (if (= outs max-out) + state + (begin + (vector-set! from-vertex sv #T) + (vector-set! edges + vertex + (cons sv + (vector-ref edges vertex))) + (let ((state + ; sv->vertex, vertex->sv + (-**- (+ sv 1) + (+ outs 1) + state))) + (vector-set! edges + vertex + (cdr (vector-ref edges vertex))) + (vector-set! from-vertex sv #F) + state))))) + (vector-set! out-degrees sv sv-out) + (vector-set! from-sv vertex #F) + (vector-set! edges + sv + (cdr (vector-ref edges sv))) + state))))) + (if (= outs max-out) + state + (begin + (vector-set! edges + vertex + (cons sv + (vector-ref edges vertex))) + (vector-set! from-vertex sv #T) + (let ((state + ; no sv->vertex, vertex->sv + (-**- (+ sv 1) + (+ outs 1) + state))) + (vector-set! from-vertex sv #F) + (vector-set! edges + vertex + (cdr (vector-ref edges vertex))) + state))))))))))))) + +; Given a vector which maps vertex to out-going-edge list, +; return a vector which gives reachability. +(define make-reach? + (lambda (size vertex->out) + (let ((res + (proc->vector size + (lambda (v) + (let ((from-v + (make-vector size #F))) + (vector-set! from-v v #T) + (for-each + (lambda (x) + (vector-set! from-v x #T)) + (vector-ref vertex->out v)) + from-v))))) + (gnatural-for-each size + (lambda (m) + (let ((from-m + (vector-ref res m))) + (gnatural-for-each size + (lambda (f) + (let ((from-f + (vector-ref res f))) + (if (vector-ref from-f m); [wdc - was when] + (begin + (gnatural-for-each size + (lambda (t) + (if (vector-ref from-m t) + (begin ; [wdc - was when] + (vector-set! from-f t #T))))))))))))) + res))) + + +;;; ==== test input ==== + +; Produces all directed graphs with N verticies, distinguished root, +; and out-degree bounded by 2, upto isomorphism (there are 44). + +;(define go +; (let ((N 7)) +; (fold-over-rdg N +; 2 +; cons +; '()))) + +(graphs-benchmark 6) diff --git a/collects/tests/mzscheme/benchmarks/common/graphs.ss b/collects/tests/mzscheme/benchmarks/common/graphs.ss new file mode 100644 index 0000000000..45d75d7458 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/graphs.ss @@ -0,0 +1,2 @@ + +(module graphs "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/nboyer.sch b/collects/tests/mzscheme/benchmarks/common/nboyer.sch new file mode 100644 index 0000000000..c7e887a29b --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nboyer.sch @@ -0,0 +1,759 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: nboyer.sch +; Description: The Boyer benchmark +; Author: Bob Boyer +; Created: 5-Apr-85 +; Modified: 10-Apr-85 14:52:20 (Bob Shaw) +; 22-Jul-87 (Will Clinger) +; 2-Jul-88 (Will Clinger -- distinguished #f and the empty list) +; 13-Feb-97 (Will Clinger -- fixed bugs in unifier and rules, +; rewrote to eliminate property lists, and added +; a scaling parameter suggested by Bob Boyer) +; 19-Mar-99 (Will Clinger -- cleaned up comments) +; 4-Apr-01 (Will Clinger -- changed four 1- symbols to sub1) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; NBOYER -- Logic programming benchmark, originally written by Bob Boyer. +;;; Fairly CONS intensive. + +; Note: The version of this benchmark that appears in Dick Gabriel's book +; contained several bugs that are corrected here. These bugs are discussed +; by Henry Baker, "The Boyer Benchmark Meets Linear Logic", ACM SIGPLAN Lisp +; Pointers 6(4), October-December 1993, pages 3-10. The fixed bugs are: +; +; The benchmark now returns a boolean result. +; FALSEP and TRUEP use TERM-MEMBER? rather than MEMV (which is called MEMBER +; in Common Lisp) +; ONE-WAY-UNIFY1 now treats numbers correctly +; ONE-WAY-UNIFY1-LST now treats empty lists correctly +; Rule 19 has been corrected (this rule was not touched by the original +; benchmark, but is used by this version) +; Rules 84 and 101 have been corrected (but these rules are never touched +; by the benchmark) +; +; According to Baker, these bug fixes make the benchmark 10-25% slower. +; Please do not compare the timings from this benchmark against those of +; the original benchmark. +; +; This version of the benchmark also prints the number of rewrites as a sanity +; check, because it is too easy for a buggy version to return the correct +; boolean result. The correct number of rewrites is +; +; n rewrites peak live storage (approximate, in bytes) +; 0 95024 520,000 +; 1 591777 2,085,000 +; 2 1813975 5,175,000 +; 3 5375678 +; 4 16445406 +; 5 51507739 + +; Nboyer is a 2-phase benchmark. +; The first phase attaches lemmas to symbols. This phase is not timed, +; but it accounts for very little of the runtime anyway. +; The second phase creates the test problem, and tests to see +; whether it is implied by the lemmas. + +(define (nboyer-benchmark . args) + (let ((n (if (null? args) 0 (car args)))) + (setup-boyer) + (time (test-boyer n)))) + +(define (setup-boyer) #t) ; assigned below +(define (test-boyer) #t) ; assigned below + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The first phase. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; In the original benchmark, it stored a list of lemmas on the +; property lists of symbols. +; In the new benchmark, it maintains an association list of +; symbols and symbol-records, and stores the list of lemmas +; within the symbol-records. + +(let () + + (define (setup) + (add-lemma-lst + (quote ((equal (compile form) + (reverse (codegen (optimize form) + (nil)))) + (equal (eqp x y) + (equal (fix x) + (fix y))) + (equal (greaterp x y) + (lessp y x)) + (equal (lesseqp x y) + (not (lessp y x))) + (equal (greatereqp x y) + (not (lessp x y))) + (equal (boolean x) + (or (equal x (t)) + (equal x (f)))) + (equal (iff x y) + (and (implies x y) + (implies y x))) + (equal (even1 x) + (if (zerop x) + (t) + (odd (sub1 x)))) + (equal (countps- l pred) + (countps-loop l pred (zero))) + (equal (fact- i) + (fact-loop i 1)) + (equal (reverse- x) + (reverse-loop x (nil))) + (equal (divides x y) + (zerop (remainder y x))) + (equal (assume-true var alist) + (cons (cons var (t)) + alist)) + (equal (assume-false var alist) + (cons (cons var (f)) + alist)) + (equal (tautology-checker x) + (tautologyp (normalize x) + (nil))) + (equal (falsify x) + (falsify1 (normalize x) + (nil))) + (equal (prime x) + (and (not (zerop x)) + (not (equal x (add1 (zero)))) + (prime1 x (sub1 x)))) + (equal (and p q) + (if p (if q (t) + (f)) + (f))) + (equal (or p q) + (if p (t) + (if q (t) + (f)))) + (equal (not p) + (if p (f) + (t))) + (equal (implies p q) + (if p (if q (t) + (f)) + (t))) + (equal (fix x) + (if (numberp x) + x + (zero))) + (equal (if (if a b c) + d e) + (if a (if b d e) + (if c d e))) + (equal (zerop x) + (or (equal x (zero)) + (not (numberp x)))) + (equal (plus (plus x y) + z) + (plus x (plus y z))) + (equal (equal (plus a b) + (zero)) + (and (zerop a) + (zerop b))) + (equal (difference x x) + (zero)) + (equal (equal (plus a b) + (plus a c)) + (equal (fix b) + (fix c))) + (equal (equal (zero) + (difference x y)) + (not (lessp y x))) + (equal (equal x (difference x y)) + (and (numberp x) + (or (equal x (zero)) + (zerop y)))) + (equal (meaning (plus-tree (append x y)) + a) + (plus (meaning (plus-tree x) + a) + (meaning (plus-tree y) + a))) + (equal (meaning (plus-tree (plus-fringe x)) + a) + (fix (meaning x a))) + (equal (append (append x y) + z) + (append x (append y z))) + (equal (reverse (append a b)) + (append (reverse b) + (reverse a))) + (equal (times x (plus y z)) + (plus (times x y) + (times x z))) + (equal (times (times x y) + z) + (times x (times y z))) + (equal (equal (times x y) + (zero)) + (or (zerop x) + (zerop y))) + (equal (exec (append x y) + pds envrn) + (exec y (exec x pds envrn) + envrn)) + (equal (mc-flatten x y) + (append (flatten x) + y)) + (equal (member x (append a b)) + (or (member x a) + (member x b))) + (equal (member x (reverse y)) + (member x y)) + (equal (length (reverse x)) + (length x)) + (equal (member a (intersect b c)) + (and (member a b) + (member a c))) + (equal (nth (zero) + i) + (zero)) + (equal (exp i (plus j k)) + (times (exp i j) + (exp i k))) + (equal (exp i (times j k)) + (exp (exp i j) + k)) + (equal (reverse-loop x y) + (append (reverse x) + y)) + (equal (reverse-loop x (nil)) + (reverse x)) + (equal (count-list z (sort-lp x y)) + (plus (count-list z x) + (count-list z y))) + (equal (equal (append a b) + (append a c)) + (equal b c)) + (equal (plus (remainder x y) + (times y (quotient x y))) + (fix x)) + (equal (power-eval (big-plus1 l i base) + base) + (plus (power-eval l base) + i)) + (equal (power-eval (big-plus x y i base) + base) + (plus i (plus (power-eval x base) + (power-eval y base)))) + (equal (remainder y 1) + (zero)) + (equal (lessp (remainder x y) + y) + (not (zerop y))) + (equal (remainder x x) + (zero)) + (equal (lessp (quotient i j) + i) + (and (not (zerop i)) + (or (zerop j) + (not (equal j 1))))) + (equal (lessp (remainder x y) + x) + (and (not (zerop y)) + (not (zerop x)) + (not (lessp x y)))) + (equal (power-eval (power-rep i base) + base) + (fix i)) + (equal (power-eval (big-plus (power-rep i base) + (power-rep j base) + (zero) + base) + base) + (plus i j)) + (equal (gcd x y) + (gcd y x)) + (equal (nth (append a b) + i) + (append (nth a i) + (nth b (difference i (length a))))) + (equal (difference (plus x y) + x) + (fix y)) + (equal (difference (plus y x) + x) + (fix y)) + (equal (difference (plus x y) + (plus x z)) + (difference y z)) + (equal (times x (difference c w)) + (difference (times c x) + (times w x))) + (equal (remainder (times x z) + z) + (zero)) + (equal (difference (plus b (plus a c)) + a) + (plus b c)) + (equal (difference (add1 (plus y z)) + z) + (add1 y)) + (equal (lessp (plus x y) + (plus x z)) + (lessp y z)) + (equal (lessp (times x z) + (times y z)) + (and (not (zerop z)) + (lessp x y))) + (equal (lessp y (plus x y)) + (not (zerop x))) + (equal (gcd (times x z) + (times y z)) + (times z (gcd x y))) + (equal (value (normalize x) + a) + (value x a)) + (equal (equal (flatten x) + (cons y (nil))) + (and (nlistp x) + (equal x y))) + (equal (listp (gopher x)) + (listp x)) + (equal (samefringe x y) + (equal (flatten x) + (flatten y))) + (equal (equal (greatest-factor x y) + (zero)) + (and (or (zerop y) + (equal y 1)) + (equal x (zero)))) + (equal (equal (greatest-factor x y) + 1) + (equal x 1)) + (equal (numberp (greatest-factor x y)) + (not (and (or (zerop y) + (equal y 1)) + (not (numberp x))))) + (equal (times-list (append x y)) + (times (times-list x) + (times-list y))) + (equal (prime-list (append x y)) + (and (prime-list x) + (prime-list y))) + (equal (equal z (times w z)) + (and (numberp z) + (or (equal z (zero)) + (equal w 1)))) + (equal (greatereqp x y) + (not (lessp x y))) + (equal (equal x (times x y)) + (or (equal x (zero)) + (and (numberp x) + (equal y 1)))) + (equal (remainder (times y x) + y) + (zero)) + (equal (equal (times a b) + 1) + (and (not (equal a (zero))) + (not (equal b (zero))) + (numberp a) + (numberp b) + (equal (sub1 a) + (zero)) + (equal (sub1 b) + (zero)))) + (equal (lessp (length (delete x l)) + (length l)) + (member x l)) + (equal (sort2 (delete x l)) + (delete x (sort2 l))) + (equal (dsort x) + (sort2 x)) + (equal (length (cons x1 + (cons x2 + (cons x3 (cons x4 + (cons x5 + (cons x6 x7))))))) + (plus 6 (length x7))) + (equal (difference (add1 (add1 x)) + 2) + (fix x)) + (equal (quotient (plus x (plus x y)) + 2) + (plus x (quotient y 2))) + (equal (sigma (zero) + i) + (quotient (times i (add1 i)) + 2)) + (equal (plus x (add1 y)) + (if (numberp y) + (add1 (plus x y)) + (add1 x))) + (equal (equal (difference x y) + (difference z y)) + (if (lessp x y) + (not (lessp y z)) + (if (lessp z y) + (not (lessp y x)) + (equal (fix x) + (fix z))))) + (equal (meaning (plus-tree (delete x y)) + a) + (if (member x y) + (difference (meaning (plus-tree y) + a) + (meaning x a)) + (meaning (plus-tree y) + a))) + (equal (times x (add1 y)) + (if (numberp y) + (plus x (times x y)) + (fix x))) + (equal (nth (nil) + i) + (if (zerop i) + (nil) + (zero))) + (equal (last (append a b)) + (if (listp b) + (last b) + (if (listp a) + (cons (car (last a)) + b) + b))) + (equal (equal (lessp x y) + z) + (if (lessp x y) + (equal (t) z) + (equal (f) z))) + (equal (assignment x (append a b)) + (if (assignedp x a) + (assignment x a) + (assignment x b))) + (equal (car (gopher x)) + (if (listp x) + (car (flatten x)) + (zero))) + (equal (flatten (cdr (gopher x))) + (if (listp x) + (cdr (flatten x)) + (cons (zero) + (nil)))) + (equal (quotient (times y x) + y) + (if (zerop y) + (zero) + (fix x))) + (equal (get j (set i val mem)) + (if (eqp j i) + val + (get j mem))))))) + + (define (add-lemma-lst lst) + (cond ((null? lst) + #t) + (else (add-lemma (car lst)) + (add-lemma-lst (cdr lst))))) + + (define (add-lemma term) + (cond ((and (pair? term) + (eq? (car term) + (quote equal)) + (pair? (cadr term))) + (put (car (cadr term)) + (quote lemmas) + (cons + (translate-term term) + (get (car (cadr term)) (quote lemmas))))) + (else (error "ADD-LEMMA did not like term: " term)))) + + ; Translates a term by replacing its constructor symbols by symbol-records. + + (define (translate-term term) + (cond ((not (pair? term)) + term) + (else (cons (symbol->symbol-record (car term)) + (translate-args (cdr term)))))) + + (define (translate-args lst) + (cond ((null? lst) + '()) + (else (cons (translate-term (car lst)) + (translate-args (cdr lst)))))) + + ; For debugging only, so the use of MAP does not change + ; the first-order character of the benchmark. + + (define (untranslate-term term) + (cond ((not (pair? term)) + term) + (else (cons (get-name (car term)) + (map untranslate-term (cdr term)))))) + + ; A symbol-record is represented as a vector with two fields: + ; the symbol (for debugging) and + ; the list of lemmas associated with the symbol. + + (define (put sym property value) + (put-lemmas! (symbol->symbol-record sym) value)) + + (define (get sym property) + (get-lemmas (symbol->symbol-record sym))) + + (define (symbol->symbol-record sym) + (let ((x (assq sym *symbol-records-alist*))) + (if x + (cdr x) + (let ((r (make-symbol-record sym))) + (set! *symbol-records-alist* + (cons (cons sym r) + *symbol-records-alist*)) + r)))) + + ; Association list of symbols and symbol-records. + + (define *symbol-records-alist* '()) + + ; A symbol-record is represented as a vector with two fields: + ; the symbol (for debugging) and + ; the list of lemmas associated with the symbol. + + (define (make-symbol-record sym) + (vector sym '())) + + (define (put-lemmas! symbol-record lemmas) + (vector-set! symbol-record 1 lemmas)) + + (define (get-lemmas symbol-record) + (vector-ref symbol-record 1)) + + (define (get-name symbol-record) + (vector-ref symbol-record 0)) + + (define (symbol-record-equal? r1 r2) + (eq? r1 r2)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; + ; The second phase. + ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (define (test n) + (let ((term + (apply-subst + (translate-alist + (quote ((x f (plus (plus a b) + (plus c (zero)))) + (y f (times (times a b) + (plus c d))) + (z f (reverse (append (append a b) + (nil)))) + (u equal (plus a b) + (difference x y)) + (w lessp (remainder a b) + (member a (length b)))))) + (translate-term + (do ((term + (quote (implies (and (implies x y) + (and (implies y z) + (and (implies z u) + (implies u w)))) + (implies x w))) + (list 'or term '(f))) + (n n (- n 1))) + ((zero? n) term)))))) + (tautp term))) + + (define (translate-alist alist) + (cond ((null? alist) + '()) + (else (cons (cons (caar alist) + (translate-term (cdar alist))) + (translate-alist (cdr alist)))))) + + (define (apply-subst alist term) + (cond ((not (pair? term)) + (let ((temp-temp (assq term alist))) + (if temp-temp + (cdr temp-temp) + term))) + (else (cons (car term) + (apply-subst-lst alist (cdr term)))))) + + (define (apply-subst-lst alist lst) + (cond ((null? lst) + '()) + (else (cons (apply-subst alist (car lst)) + (apply-subst-lst alist (cdr lst)))))) + + (define (tautp x) + (tautologyp (rewrite x) + '() '())) + + (define (tautologyp x true-lst false-lst) + (cond ((truep x true-lst) + #t) + ((falsep x false-lst) + #f) + ((not (pair? x)) + #f) + ((eq? (car x) if-constructor) + (cond ((truep (cadr x) + true-lst) + (tautologyp (caddr x) + true-lst false-lst)) + ((falsep (cadr x) + false-lst) + (tautologyp (cadddr x) + true-lst false-lst)) + (else (and (tautologyp (caddr x) + (cons (cadr x) + true-lst) + false-lst) + (tautologyp (cadddr x) + true-lst + (cons (cadr x) + false-lst)))))) + (else #f))) + + (define if-constructor '*) ; becomes (symbol->symbol-record 'if) + + (define rewrite-count 0) ; sanity check + + (define (rewrite term) + (set! rewrite-count (+ rewrite-count 1)) + (cond ((not (pair? term)) + term) + (else (rewrite-with-lemmas (cons (car term) + (rewrite-args (cdr term))) + (get-lemmas (car term)))))) + + (define (rewrite-args lst) + (cond ((null? lst) + '()) + (else (cons (rewrite (car lst)) + (rewrite-args (cdr lst)))))) + + (define (rewrite-with-lemmas term lst) + (cond ((null? lst) + term) + ((one-way-unify term (cadr (car lst))) + (rewrite (apply-subst unify-subst (caddr (car lst))))) + (else (rewrite-with-lemmas term (cdr lst))))) + + (define unify-subst '*) + + (define (one-way-unify term1 term2) + (begin (set! unify-subst '()) + (one-way-unify1 term1 term2))) + + (define (one-way-unify1 term1 term2) + (cond ((not (pair? term2)) + (let ((temp-temp (assq term2 unify-subst))) + (cond (temp-temp + (term-equal? term1 (cdr temp-temp))) + ((number? term2) ; This bug fix makes + (equal? term1 term2)) ; nboyer 10-25% slower! + (else + (set! unify-subst (cons (cons term2 term1) + unify-subst)) + #t)))) + ((not (pair? term1)) + #f) + ((eq? (car term1) + (car term2)) + (one-way-unify1-lst (cdr term1) + (cdr term2))) + (else #f))) + + (define (one-way-unify1-lst lst1 lst2) + (cond ((null? lst1) + (null? lst2)) + ((null? lst2) + #f) + ((one-way-unify1 (car lst1) + (car lst2)) + (one-way-unify1-lst (cdr lst1) + (cdr lst2))) + (else #f))) + + (define (falsep x lst) + (or (term-equal? x false-term) + (term-member? x lst))) + + (define (truep x lst) + (or (term-equal? x true-term) + (term-member? x lst))) + + (define false-term '*) ; becomes (translate-term '(f)) + (define true-term '*) ; becomes (translate-term '(t)) + + ; The next two procedures were in the original benchmark + ; but were never used. + + (define (trans-of-implies n) + (translate-term + (list (quote implies) + (trans-of-implies1 n) + (list (quote implies) + 0 n)))) + + (define (trans-of-implies1 n) + (cond ((equal? n 1) + (list (quote implies) + 0 1)) + (else (list (quote and) + (list (quote implies) + (- n 1) + n) + (trans-of-implies1 (- n 1)))))) + + ; Translated terms can be circular structures, which can't be + ; compared using Scheme's equal? and member procedures, so we + ; use these instead. + + (define (term-equal? x y) + (cond ((pair? x) + (and (pair? y) + (symbol-record-equal? (car x) (car y)) + (term-args-equal? (cdr x) (cdr y)))) + (else (equal? x y)))) + + (define (term-args-equal? lst1 lst2) + (cond ((null? lst1) + (null? lst2)) + ((null? lst2) + #f) + ((term-equal? (car lst1) (car lst2)) + (term-args-equal? (cdr lst1) (cdr lst2))) + (else #f))) + + (define (term-member? x lst) + (cond ((null? lst) + #f) + ((term-equal? x (car lst)) + #t) + (else (term-member? x (cdr lst))))) + + (set! setup-boyer + (lambda () + (set! *symbol-records-alist* '()) + (set! if-constructor (symbol->symbol-record 'if)) + (set! false-term (translate-term '(f))) + (set! true-term (translate-term '(t))) + (setup))) + + (set! test-boyer + (lambda (n) + (set! rewrite-count 0) + (let ((answer (test n))) + (write rewrite-count) + (display " rewrites") + (newline) + (if answer + rewrite-count + #f))))) + +(nboyer-benchmark 4) + diff --git a/collects/tests/mzscheme/benchmarks/common/nboyer.ss b/collects/tests/mzscheme/benchmarks/common/nboyer.ss new file mode 100644 index 0000000000..2f3e901883 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nboyer.ss @@ -0,0 +1,2 @@ + +(module nboyer "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/nfa.sch b/collects/tests/mzscheme/benchmarks/common/nfa.sch new file mode 100644 index 0000000000..0bf435c25a --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nfa.sch @@ -0,0 +1,48 @@ +; The recursive-nfa benchmark. (Figure 45, page 143.) + +(define (recursive-nfa input) + + (define (state0 input) + (or (state1 input) (state3 input) #f)) + + (define (state1 input) + (and (not (null? input)) + (or (and (char=? (car input) #\a) + (state1 (cdr input))) + (and (char=? (car input) #\c) + (state1 input)) + (state2 input)))) + + (define (state2 input) + (and (not (null? input)) + (char=? (car input) #\b) + (not (null? (cdr input))) + (char=? (cadr input) #\c) + (not (null? (cddr input))) + (char=? (caddr input) #\d) + 'state2)) + + (define (state3 input) + (and (not (null? input)) + (or (and (char=? (car input) #\a) + (state3 (cdr input))) + (state4 input)))) + + (define (state4 input) + (and (not (null? input)) + (char=? (car input) #\b) + (not (null? (cdr input))) + (char=? (cadr input) #\c) + 'state4)) + + (or (state0 (string->list input)) + 'fail)) + +(time (let ([input (string-append (make-string 133 #\a) "bc")]) + (let loop ([n 10000]) + (unless (zero? n) + (recursive-nfa input) + (loop (sub1 n)))))) + + + diff --git a/collects/tests/mzscheme/benchmarks/common/nfa.ss b/collects/tests/mzscheme/benchmarks/common/nfa.ss new file mode 100644 index 0000000000..1f9a6d657d --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nfa.ss @@ -0,0 +1,2 @@ + +(module nfa "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/nucleic2.sch b/collects/tests/mzscheme/benchmarks/common/nucleic2.sch new file mode 100644 index 0000000000..048d6b00b9 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nucleic2.sch @@ -0,0 +1,3759 @@ +; File: "nucleic2.scm" +; +; Author: Marc Feeley (feeley@iro.umontreal.ca) +; Last modification by Feeley: June 6, 1994. +; Modified for R5RS Scheme by William D Clinger: 22 October 1996. +; Last modification by Clinger: 19 March 1999. +; +; This program is a modified version of the program described in +; +; M. Feeley, M. Turcotte, G. Lapalme. Using Multilisp for Solving +; Constraint Satisfaction Problems: an Application to Nucleic Acid 3D +; Structure Determination. Lisp and Symbolic Computation 7(2/3), +; 231-246, 1994. +; +; The differences between this program and the original are described in +; +; P.H. Hartel, M. Feeley, et al. Benchmarking Implementations of +; Functional Languages with "Pseudoknot", a Float-Intensive Benchmark. +; Journal of Functional Programming 6(4), 621-655, 1996. + +; This procedure uses Marc Feeley's run-benchmark procedure to time +; the benchmark. + +; PORTABILITY. +; +; This program should run in any R5RS-conforming implementation of Scheme. +; To run this program in an implementation that does not support the R5RS +; macro system, however, you will have to place a single quotation mark (') +; on the following line and also modify the "SYSTEM DEPENDENT CODE" below. + +; ********** R5RS Scheme + +(begin + +(define-syntax FLOAT+ (syntax-rules () ((FLOAT+ x ...) (+ x ...)))) +(define-syntax FLOAT- (syntax-rules () ((FLOAT- x ...) (- x ...)))) +(define-syntax FLOAT* (syntax-rules () ((FLOAT* x ...) (* x ...)))) +(define-syntax FLOAT/ (syntax-rules () ((FLOAT/ x ...) (/ x ...)))) +(define-syntax FLOAT= (syntax-rules () ((FLOAT= x y) (= x y)))) +(define-syntax FLOAT< (syntax-rules () ((FLOAT< x y) (< x y)))) +(define-syntax FLOAT<= (syntax-rules () ((FLOAT<= x y) (<= x y)))) +(define-syntax FLOAT> (syntax-rules () ((FLOAT> x y) (> x y)))) +(define-syntax FLOAT>= (syntax-rules () ((FLOAT>= x y) (>= x y)))) +(define-syntax FLOATsin (syntax-rules () ((FLOATsin x) (sin x)))) +(define-syntax FLOATcos (syntax-rules () ((FLOATcos x) (cos x)))) +(define-syntax FLOATatan (syntax-rules () ((FLOATatan x) (atan x)))) +(define-syntax FLOATsqrt (syntax-rules () ((FLOATsqrt x) (sqrt x)))) + +(define-syntax FUTURE (syntax-rules () ((FUTURE x) x))) +(define-syntax TOUCH (syntax-rules () ((TOUCH x) x))) + +(define-syntax def-macro (syntax-rules () ((def-macro stuff ...) #t))) +(define-syntax def-struct (syntax-rules () ((def-macro stuff ...) #t))) +(define-syntax def-nuc (syntax-rules () ((def-nuc stuff ...) #t))) + +(define-syntax define-structure + (syntax-rules () + ((define-structure #f + name make make-constant (select1 ...) (set1 ...)) + (begin (define-syntax make + (syntax-rules () + ((make select1 ...) + (vector select1 ...)))) + (define-syntax make-constant + (syntax-rules () + ; The vectors that are passed to make-constant aren't quoted. + ((make-constant . args) + (constant-maker make . args)))) + (define-selectors (select1 ...) + (0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49)) + (define-setters (set1 ...) + (0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49)))) + ((define-structure pred? + name make make-constant (select1 ...) (set1 ...)) + (begin (define-syntax pred? + (syntax-rules () + ((pred? v) + (and (vector? v) (eq? (vector-ref v 0) 'name))))) + (define-syntax make + (syntax-rules () + ((make select1 ...) + (vector 'name select1 ...)))) + (define-syntax make-constant + (syntax-rules () + ; The vectors that are passed to make-constant aren't quoted. + ((make-constant . args) + (constant-maker make . args)))) + (define-selectors (select1 ...) + (1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49)) + (define-setters (set1 ...) + (1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49)))))) +(define-syntax constant-maker + (syntax-rules () + ; The quotation marks are added here. + ((constant-maker make arg ...) + (make 'arg ...)))) +(define-syntax define-selectors + (syntax-rules () + ((define-selectors (select) (i i1 ...)) + (define-syntax select + (syntax-rules () + ((select v) (vector-ref v i))))) + ((define-selectors (select select1 ...) (i i1 ...)) + (begin (define-syntax select + (syntax-rules () + ((select v) (vector-ref v i)))) + (define-selectors (select1 ...) (i1 ...)))))) +(define-syntax define-setters + (syntax-rules () + ((define-setters (set) (i i1 ...)) + (define-syntax set + (syntax-rules () + ((set v x) (vector-set! v i x))))) + ((define-setters (set set1 ...) (i i1 ...)) + (begin (define-syntax set + (syntax-rules () + ((set v x) (vector-set! v i x)))) + (define-setters (set1 ...) (i1 ...)))))) + +(define-structure #f pt + make-pt make-constant-pt + (pt-x pt-y pt-z) + (pt-x-set! pt-y-set! pt-z-set!)) + +(define-structure #f tfo + make-tfo make-constant-tfo + (tfo-a tfo-b tfo-c tfo-d tfo-e tfo-f tfo-g tfo-h tfo-i tfo-tx tfo-ty tfo-tz) + (tfo-a-set! tfo-b-set! tfo-c-set! tfo-d-set! tfo-e-set! tfo-f-set! + tfo-g-set! tfo-h-set! tfo-i-set! tfo-tx-set! tfo-ty-set! tfo-tz-set!)) + +(define-structure nuc? nuc + make-nuc make-constant-nuc + (nuc-dgf-base-tfo ; defines the standard position for wc and wc-dumas + nuc-P-O3*-275-tfo ; defines the standard position for the connect function + nuc-P-O3*-180-tfo + nuc-P-O3*-60-tfo + nuc-P nuc-O1P nuc-O2P nuc-O5* nuc-C5* + nuc-H5* nuc-H5** + nuc-C4* nuc-H4* nuc-O4* nuc-C1* nuc-H1* + nuc-C2* nuc-H2** + nuc-O2* nuc-H2* nuc-C3* nuc-H3* nuc-O3* + nuc-N1 nuc-N3 nuc-C2 nuc-C4 nuc-C5 nuc-C6) + (nuc-dgf-base-tfo-set! + nuc-P-O3*-275-tfo-set! + nuc-P-O3*-180-tfo-set! + nuc-P-O3*-60-tfo-set! + nuc-P-set! nuc-O1P-set! nuc-O2P-set! nuc-O5*-set! nuc-C5*-set! + nuc-H5*-set! nuc-H5**-set! + nuc-C4*-set! nuc-H4*-set! nuc-O4*-set! nuc-C1*-set! nuc-H1*-set! + nuc-C2*-set! nuc-H2**-set! + nuc-O2*-set! nuc-H2*-set! nuc-C3*-set! nuc-H3*-set! nuc-O3*-set! + nuc-N1-set! nuc-N3-set! nuc-C2-set! nuc-C4-set! nuc-C5-set! nuc-C6-set!)) + +(define-structure rA? rA + make-rA make-constant-rA + (rA-dgf-base-tfo ; defines the standard position for wc and wc-dumas + rA-P-O3*-275-tfo ; defines the standard position for the connect function + rA-P-O3*-180-tfo + rA-P-O3*-60-tfo + rA-P rA-O1P rA-O2P rA-O5* rA-C5* + rA-H5* rA-H5** + rA-C4* rA-H4* rA-O4* rA-C1* rA-H1* + rA-C2* rA-H2** + rA-O2* rA-H2* rA-C3* rA-H3* rA-O3* + rA-N1 rA-N3 rA-C2 rA-C4 rA-C5 rA-C6 + rA-N6 rA-N7 rA-N9 rA-C8 + rA-H2 rA-H61 rA-H62 rA-H8) + (rA-dgf-base-tfo-set! + rA-P-O3*-275-tfo-set! + rA-P-O3*-180-tfo-set! + rA-P-O3*-60-tfo-set! + rA-P-set! rA-O1P-set! rA-O2P-set! rA-O5*-set! rA-C5*-set! + rA-H5*-set! rA-H5**-set! + rA-C4*-set! rA-H4*-set! rA-O4*-set! rA-C1*-set! rA-H1*-set! + rA-C2*-set! rA-H2**-set! + rA-O2*-set! rA-H2*-set! rA-C3*-set! rA-H3*-set! rA-O3*-set! + rA-N1-set! rA-N3-set! rA-C2-set! rA-C4-set! rA-C5-set! rA-C6-set! + rA-N6-set! rA-N7-set! rA-N9-set! rA-C8-set! + rA-H2-set! rA-H61-set! rA-H62-set! rA-H8-set!)) + +(define-structure rC? rC + make-rC make-constant-rC + (rC-dgf-base-tfo ; defines the standard position for wc and wc-dumas + rC-P-O3*-275-tfo ; defines the standard position for the connect function + rC-P-O3*-180-tfo + rC-P-O3*-60-tfo + rC-P rC-O1P rC-O2P rC-O5* rC-C5* + rC-H5* rC-H5** + rC-C4* rC-H4* rC-O4* rC-C1* rC-H1* + rC-C2* rC-H2** + rC-O2* rC-H2* rC-C3* rC-H3* rC-O3* + rC-N1 rC-N3 rC-C2 rC-C4 rC-C5 rC-C6 + rC-N4 rC-O2 rC-H41 rC-H42 rC-H5 rC-H6) + (rC-dgf-base-tfo-set! + rC-P-O3*-275-tfo-set! + rC-P-O3*-180-tfo-set! + rC-P-O3*-60-tfo-set! + rC-P-set! rC-O1P-set! rC-O2P-set! rC-O5*-set! rC-C5*-set! + rC-H5*-set! rC-H5**-set! + rC-C4*-set! rC-H4*-set! rC-O4*-set! rC-C1*-set! rC-H1*-set! + rC-C2*-set! rC-H2**-set! + rC-O2*-set! rC-H2*-set! rC-C3*-set! rC-H3*-set! rC-O3*-set! + rC-N1-set! rC-N3-set! rC-C2-set! rC-C4-set! rC-C5-set! rC-C6-set! + rC-N4-set! rC-O2-set! rC-H41-set! rC-H42-set! rC-H5-set! rC-H6-set!)) + +(define-structure rG? rG + make-rG make-constant-rG + (rG-dgf-base-tfo ; defines the standard position for wc and wc-dumas + rG-P-O3*-275-tfo ; defines the standard position for the connect function + rG-P-O3*-180-tfo + rG-P-O3*-60-tfo + rG-P rG-O1P rG-O2P rG-O5* rG-C5* + rG-H5* rG-H5** + rG-C4* rG-H4* rG-O4* rG-C1* rG-H1* + rG-C2* rG-H2** + rG-O2* rG-H2* rG-C3* rG-H3* rG-O3* + rG-N1 rG-N3 rG-C2 rG-C4 rG-C5 rG-C6 + rG-N2 rG-N7 rG-N9 rG-C8 rG-O6 + rG-H1 rG-H21 rG-H22 rG-H8) + (rG-dgf-base-tfo-set! + rG-P-O3*-275-tfo-set! + rG-P-O3*-180-tfo-set! + rG-P-O3*-60-tfo-set! + rG-P-set! rG-O1P-set! rG-O2P-set! rG-O5*-set! rG-C5*-set! + rG-H5*-set! rG-H5**-set! + rG-C4*-set! rG-H4*-set! rG-O4*-set! rG-C1*-set! rG-H1*-set! + rG-C2*-set! rG-H2**-set! + rG-O2*-set! rG-H2*-set! rG-C3*-set! rG-H3*-set! rG-O3*-set! + rG-N1-set! rG-N3-set! rG-C2-set! rG-C4-set! rG-C5-set! rG-C6-set! + rG-N2-set! rG-N7-set! rG-N9-set! rG-C8-set! rG-O6-set! + rG-H1-set! rG-H21-set! rG-H22-set! rG-H8-set!)) + +(define-structure rU? rU + make-rU make-constant-rU + (rU-dgf-base-tfo ; defines the standard position for wc and wc-dumas + rU-P-O3*-275-tfo ; defines the standard position for the connect function + rU-P-O3*-180-tfo + rU-P-O3*-60-tfo + rU-P rU-O1P rU-O2P rU-O5* rU-C5* + rU-H5* rU-H5** + rU-C4* rU-H4* rU-O4* rU-C1* rU-H1* + rU-C2* rU-H2** + rU-O2* rU-H2* rU-C3* rU-H3* rU-O3* + rU-N1 rU-N3 rU-C2 rU-C4 rU-C5 rU-C6 + rU-O2 rU-O4 rU-H3 rU-H5 rU-H6) + (rU-dgf-base-tfo-set! + rU-P-O3*-275-tfo-set! + rU-P-O3*-180-tfo-set! + rU-P-O3*-60-tfo-set! + rU-P-set! rU-O1P-set! rU-O2P-set! rU-O5*-set! rU-C5*-set! + rU-H5*-set! rU-H5**-set! + rU-C4*-set! rU-H4*-set! rU-O4*-set! rU-C1*-set! rU-H1*-set! + rU-C2*-set! rU-H2**-set! + rU-O2*-set! rU-H2*-set! rU-C3*-set! rU-H3*-set! rU-O3*-set! + rU-N1-set! rU-N3-set! rU-C2-set! rU-C4-set! rU-C5-set! rU-C6-set! + rU-O2-set! rU-O4-set! rU-H3-set! rU-H5-set! rU-H6-set!)) + +(define-structure #f var + make-var make-constant-var + (var-id var-tfo var-nuc) + (var-id-set! var-tfo-set! var-nuc-set!)) + +; Comment out the next three syntax definitions if you want +; lazy computation. + +(define-syntax mk-var + (syntax-rules () + ((mk-var i tfo nuc) + (make-var i tfo nuc)))) + +(define-syntax absolute-pos + (syntax-rules () + ((absolute-pos var p) + (tfo-apply (var-tfo var) p)))) + +(define-syntax lazy-computation-of + (syntax-rules () + ((lazy-computation-of expr) + expr))) + +; Uncomment the next three syntax definitions if you want +; lazy computation. + +; (define-syntax mk-var +; (syntax-rules () +; ((mk-var i tfo nuc) +; (make-var i tfo (make-relative-nuc tfo nuc))))) +; +; (define-syntax absolute-pos +; (syntax-rules () +; ((absolute-pos var p) +; (force p)))) +; +; (define-syntax lazy-computation-of +; (syntax-rules () +; ((lazy-computation-of expr) +; (delay expr)))) + +(define-syntax atom-pos + (syntax-rules () + ((atom-pos atom var) + (let ((v var)) + (absolute-pos v (atom (var-nuc v))))))) + +) + +; -- SYSTEM DEPENDENT CODE ---------------------------------------------------- + +; The code in this section is not portable. It must be adapted to +; the Scheme system you are using. + +; ********** GAMBIT 2.2 + +'; Add a single-quote at the start of this line if you are NOT using Gambit +(begin + +(declare ; Compiler declarations for fast code: + (multilisp) ; - Enable the FUTURE special-form + (block) ; - Assume this file contains the entire program + (standard-bindings) ; - Assume standard bindings (this permits open-coding) + (extended-bindings) ; - Same for extensions (such as "##flonum.+") + (fixnum) ; - Use fixnum arithmetic by default + (not safe) ; - Remove all runtime type checks +) + +(define-macro (def-macro form . body) + `(DEFINE-MACRO ,form (LET () ,@body))) + +(def-macro (FLOAT+ x . l) `(,(string->symbol "##flonum.+") ,x ,@l)) +(def-macro (FLOAT- x . l) `(,(string->symbol "##flonum.-") ,x ,@l)) +(def-macro (FLOAT* x . l) `(,(string->symbol "##flonum.*") ,x ,@l)) +(def-macro (FLOAT/ x . l) `(,(string->symbol "##flonum./") ,x ,@l)) +(def-macro (FLOAT= x y) `(,(string->symbol "##flonum.=") ,x ,y)) +(def-macro (FLOAT< x y) `(,(string->symbol "##flonum.<") ,x ,y)) +(def-macro (FLOAT<= x y) `(not (,(string->symbol "##flonum.<") ,y ,x))) +(def-macro (FLOAT> x y) `(,(string->symbol "##flonum.<") ,y ,x)) +(def-macro (FLOAT>= x y) `(not (,(string->symbol "##flonum.<") ,x ,y))) +(def-macro (FLOATsin x) `(,(string->symbol "##flonum.sin") ,x)) +(def-macro (FLOATcos x) `(,(string->symbol "##flonum.cos") ,x)) +(def-macro (FLOATatan x) `(,(string->symbol "##flonum.atan") ,x)) +(def-macro (FLOATsqrt x) `(,(string->symbol "##flonum.sqrt") ,x)) +) + +; ********** MIT-SCHEME + +'; Remove the single-quote from this line if you are using MIT-Scheme +(begin + +(declare (usual-integrations)) + +(define-macro (def-macro form . body) + `(DEFINE-MACRO ,form (LET () ,@body))) + +(def-macro (nary-function op1 op2 args) + (if (null? (cdr args)) + `(,op1 ,@args) + (let loop ((args args)) + (if (null? (cdr args)) + (car args) + (loop (cons (list op2 (car args) (cadr args)) (cddr args))))))) + +(def-macro (FLOAT+ x . l) `(nary-function begin flo:+ ,(cons x l))) +(def-macro (FLOAT- x . l) `(nary-function flo:negate flo:- ,(cons x l))) +(def-macro (FLOAT* x . l) `(nary-function begin flo:* ,(cons x l))) +(def-macro (FLOAT/ x . l) `(nary-function error flo:/ ,(cons x l))) +(def-macro (FLOAT= x y) `(flo:= ,x ,y)) +(def-macro (FLOAT< x y) `(flo:< ,x ,y)) +(def-macro (FLOAT<= x y) `(not (flo:< ,y ,x))) +(def-macro (FLOAT> x y) `(flo:< ,y ,x)) +(def-macro (FLOAT>= x y) `(not (flo:< ,x ,y))) +(def-macro (FLOATsin x) `(flo:sin ,x)) +(def-macro (FLOATcos x) `(flo:cos ,x)) +(def-macro (FLOATatan x) `(flo:atan ,x)) +(def-macro (FLOATsqrt x) `(flo:sqrt ,x)) + +(def-macro (FUTURE x) x) +(def-macro (TOUCH x) x) +) + +; ********** SCM + +'; Remove the single-quote from this line if you are using SCM +(begin + +(defmacro def-macro (form . body) + `(DEFMACRO ,(car form) ,(cdr form) (LET () ,@body))) + +(def-macro (FLOAT+ x . l) `(+ ,x ,@l)) +(def-macro (FLOAT- x . l) `(- ,x ,@l)) +(def-macro (FLOAT* x . l) `(* ,x ,@l)) +(def-macro (FLOAT/ x . l) `(/ ,x ,@l)) +(def-macro (FLOAT= x y) `(= ,x ,y)) +(def-macro (FLOAT< x y) `(< ,x ,y)) +(def-macro (FLOAT<= x y) `(not (< ,y ,x))) +(def-macro (FLOAT> x y) `(< ,y ,x)) +(def-macro (FLOAT>= x y) `(not (< ,x ,y))) +(def-macro (FLOATsin x) `(sin ,x)) +(def-macro (FLOATcos x) `(cos ,x)) +(def-macro (FLOATatan x) `(atan ,x)) +(def-macro (FLOATsqrt x) `(sqrt ,x)) + +(def-macro (FUTURE x) x) +(def-macro (TOUCH x) x) +) + +; -- STRUCTURE DEFINITION MACRO ----------------------------------------------- + +; The macro "def-struct" provides a simple mechanism to define record +; structures out of vectors. The first argument to "def-struct" is a boolean +; indicating whether the vector should be tagged (to allow the type of the +; structure to be tested). The second argument is the name of the structure. +; The remaining arguments are the names of the structure's fields. A call +; to "def-struct" defines macros to +; +; 1) construct a record object of this type +; 2) fetch and store each field +; 3) test a record to see if it is of this type (only if tags are used) +; 4) define subclasses of this record with additional fields +; +; The call "(def-struct #t foo a b c)" will define the following macros: +; +; (make-foo x y) -- make a record +; (make-constant-foo x y) -- make a record (args must be constants) +; (foo? x) -- test a record +; (foo-a x) -- get field "a" +; (foo-b x) -- get field "b" +; (foo-a-set! x y) -- mutate field "a" +; (foo-b-set! x y) -- mutate field "b" +; (def-foo tag? name fields...) -- define subclass of "foo" + +(def-macro (def-struct tag? name . fields) + `(DEF-SUBSTRUCT () () 0 ,tag? ,name ,@fields)) + +(def-macro (def-substruct sup-fields sup-tags sup-length tag? name . fields) + + (define (err) + (error "Ill-formed `def-substruct'") #f) + + (define (sym . strings) + (string->symbol (apply string-append strings))) + + (if (symbol? name) + (let* ((name-str (symbol->string name)) + (tag (sym "." name-str ".")) + (all-tags (append sup-tags + (if tag? + (list (cons tag sup-length)) + '())))) + (let loop ((l1 fields) + (l2 '()) + (l3 '()) + (i (+ sup-length (if tag? 1 0)))) + (if (pair? l1) + (let ((rest (cdr l1)) (field (car l1))) + (if (symbol? field) + (let* ((field-str (symbol->string field)) + (field-ref (sym name-str "-" field-str)) + (field-set! (sym name-str "-" field-str "-set!"))) + (loop rest + (cons `(DEF-MACRO (,field-set! X Y) + `(VECTOR-SET! ,X ,,i ,Y)) + (cons `(DEF-MACRO (,field-ref X) + `(VECTOR-REF ,X ,,i)) + l2)) + (cons (cons field i) l3) + (+ i 1))) + (err))) + (let ((all-fields (append sup-fields (reverse l3)))) + `(BEGIN + ,@l2 + (DEFINE ,(sym "fields-of-" name-str) + ',all-fields) + (DEF-MACRO (,(sym "def-" name-str) TAG? NAME . FIELDS) + `(DEF-SUBSTRUCT ,',all-fields ,',all-tags ,',i + ,TAG? ,NAME ,@FIELDS)) + (DEF-MACRO (,(sym "make-constant-" name-str) . REST) + (DEFINE (ADD-TAGS I TAGS LST) + (COND ((NULL? TAGS) + LST) + ((= I (CDAR TAGS)) + (CONS (CAAR TAGS) + (ADD-TAGS (+ I 1) (CDR TAGS) LST))) + (ELSE + (CONS (CAR LST) + (ADD-TAGS (+ I 1) TAGS (CDR LST)))))) + `'#(,@(ADD-TAGS 0 ',all-tags REST))) + (DEF-MACRO (,(sym "make-" name-str) . REST) + (DEFINE (ADD-TAGS I TAGS LST) + (COND ((NULL? TAGS) + LST) + ((= I (CDAR TAGS)) + (CONS `',(CAAR TAGS) + (ADD-TAGS (+ I 1) (CDR TAGS) LST))) + (ELSE + (CONS (CAR LST) + (ADD-TAGS (+ I 1) TAGS (CDR LST)))))) + `(VECTOR ,@(ADD-TAGS 0 ',all-tags REST))) + ,@(if tag? + `((DEF-MACRO (,(sym name-str "?") X) + `(EQ? (VECTOR-REF ,X ,,sup-length) ',',tag))) + '()) + ',name))))) + (err))) + +; -- MATH UTILITIES ----------------------------------------------------------- + +(define constant-pi 3.14159265358979323846) +(define constant-minus-pi -3.14159265358979323846) +(define constant-pi/2 1.57079632679489661923) +(define constant-minus-pi/2 -1.57079632679489661923) + +(define (math-atan2 y x) + (cond ((FLOAT> x 0.0) + (FLOATatan (FLOAT/ y x))) + ((FLOAT< y 0.0) + (if (FLOAT= x 0.0) + constant-minus-pi/2 + (FLOAT+ (FLOATatan (FLOAT/ y x)) constant-minus-pi))) + (else + (if (FLOAT= x 0.0) + constant-pi/2 + (FLOAT+ (FLOATatan (FLOAT/ y x)) constant-pi))))) + +; -- POINTS ------------------------------------------------------------------- + +(def-struct #f pt x y z) + +(define (pt-sub p1 p2) + (make-pt (FLOAT- (pt-x p1) (pt-x p2)) + (FLOAT- (pt-y p1) (pt-y p2)) + (FLOAT- (pt-z p1) (pt-z p2)))) + +(define (pt-dist p1 p2) + (let ((dx (FLOAT- (pt-x p1) (pt-x p2))) + (dy (FLOAT- (pt-y p1) (pt-y p2))) + (dz (FLOAT- (pt-z p1) (pt-z p2)))) + (FLOATsqrt (FLOAT+ (FLOAT* dx dx) (FLOAT* dy dy) (FLOAT* dz dz))))) + +(define (pt-phi p) + (let* ((x (pt-x p)) + (y (pt-y p)) + (z (pt-z p)) + (b (math-atan2 x z))) + (math-atan2 (FLOAT+ (FLOAT* (FLOATcos b) z) (FLOAT* (FLOATsin b) x)) y))) + +(define (pt-theta p) + (math-atan2 (pt-x p) (pt-z p))) + +; -- COORDINATE TRANSFORMATIONS ----------------------------------------------- + +; The notation for the transformations follows "Paul, R.P. (1981) Robot +; Manipulators. MIT Press." with the exception that our transformation +; matrices don't have the perspective terms and are the transpose of +; Paul's one. See also "M\"antyl\"a, M. (1985) An Introduction to +; Solid Modeling, Computer Science Press" Appendix A. +; +; The components of a transformation matrix are named like this: +; +; a b c +; d e f +; g h i +; tx ty tz +; +; The components tx, ty, and tz are the translation vector. + +(def-struct #f tfo a b c d e f g h i tx ty tz) + +(define tfo-id ; the identity transformation matrix + '#(1.0 0.0 0.0 + 0.0 1.0 0.0 + 0.0 0.0 1.0 + 0.0 0.0 0.0)) + +; The function "tfo-apply" multiplies a transformation matrix, tfo, by a +; point vector, p. The result is a new point. + +(define (tfo-apply tfo p) + (let ((x (pt-x p)) + (y (pt-y p)) + (z (pt-z p))) + (make-pt + (FLOAT+ (FLOAT* x (tfo-a tfo)) + (FLOAT* y (tfo-d tfo)) + (FLOAT* z (tfo-g tfo)) + (tfo-tx tfo)) + (FLOAT+ (FLOAT* x (tfo-b tfo)) + (FLOAT* y (tfo-e tfo)) + (FLOAT* z (tfo-h tfo)) + (tfo-ty tfo)) + (FLOAT+ (FLOAT* x (tfo-c tfo)) + (FLOAT* y (tfo-f tfo)) + (FLOAT* z (tfo-i tfo)) + (tfo-tz tfo))))) + +; The function "tfo-combine" multiplies two transformation matrices A and B. +; The result is a new matrix which cumulates the transformations described +; by A and B. + +(define (tfo-combine A B) + (make-tfo + (FLOAT+ (FLOAT* (tfo-a A) (tfo-a B)) + (FLOAT* (tfo-b A) (tfo-d B)) + (FLOAT* (tfo-c A) (tfo-g B))) + (FLOAT+ (FLOAT* (tfo-a A) (tfo-b B)) + (FLOAT* (tfo-b A) (tfo-e B)) + (FLOAT* (tfo-c A) (tfo-h B))) + (FLOAT+ (FLOAT* (tfo-a A) (tfo-c B)) + (FLOAT* (tfo-b A) (tfo-f B)) + (FLOAT* (tfo-c A) (tfo-i B))) + (FLOAT+ (FLOAT* (tfo-d A) (tfo-a B)) + (FLOAT* (tfo-e A) (tfo-d B)) + (FLOAT* (tfo-f A) (tfo-g B))) + (FLOAT+ (FLOAT* (tfo-d A) (tfo-b B)) + (FLOAT* (tfo-e A) (tfo-e B)) + (FLOAT* (tfo-f A) (tfo-h B))) + (FLOAT+ (FLOAT* (tfo-d A) (tfo-c B)) + (FLOAT* (tfo-e A) (tfo-f B)) + (FLOAT* (tfo-f A) (tfo-i B))) + (FLOAT+ (FLOAT* (tfo-g A) (tfo-a B)) + (FLOAT* (tfo-h A) (tfo-d B)) + (FLOAT* (tfo-i A) (tfo-g B))) + (FLOAT+ (FLOAT* (tfo-g A) (tfo-b B)) + (FLOAT* (tfo-h A) (tfo-e B)) + (FLOAT* (tfo-i A) (tfo-h B))) + (FLOAT+ (FLOAT* (tfo-g A) (tfo-c B)) + (FLOAT* (tfo-h A) (tfo-f B)) + (FLOAT* (tfo-i A) (tfo-i B))) + (FLOAT+ (FLOAT* (tfo-tx A) (tfo-a B)) + (FLOAT* (tfo-ty A) (tfo-d B)) + (FLOAT* (tfo-tz A) (tfo-g B)) + (tfo-tx B)) + (FLOAT+ (FLOAT* (tfo-tx A) (tfo-b B)) + (FLOAT* (tfo-ty A) (tfo-e B)) + (FLOAT* (tfo-tz A) (tfo-h B)) + (tfo-ty B)) + (FLOAT+ (FLOAT* (tfo-tx A) (tfo-c B)) + (FLOAT* (tfo-ty A) (tfo-f B)) + (FLOAT* (tfo-tz A) (tfo-i B)) + (tfo-tz B)))) + +; The function "tfo-inv-ortho" computes the inverse of a homogeneous +; transformation matrix. + +(define (tfo-inv-ortho tfo) + (let* ((tx (tfo-tx tfo)) + (ty (tfo-ty tfo)) + (tz (tfo-tz tfo))) + (make-tfo + (tfo-a tfo) (tfo-d tfo) (tfo-g tfo) + (tfo-b tfo) (tfo-e tfo) (tfo-h tfo) + (tfo-c tfo) (tfo-f tfo) (tfo-i tfo) + (FLOAT- (FLOAT+ (FLOAT* (tfo-a tfo) tx) + (FLOAT* (tfo-b tfo) ty) + (FLOAT* (tfo-c tfo) tz))) + (FLOAT- (FLOAT+ (FLOAT* (tfo-d tfo) tx) + (FLOAT* (tfo-e tfo) ty) + (FLOAT* (tfo-f tfo) tz))) + (FLOAT- (FLOAT+ (FLOAT* (tfo-g tfo) tx) + (FLOAT* (tfo-h tfo) ty) + (FLOAT* (tfo-i tfo) tz)))))) + +; Given three points p1, p2, and p3, the function "tfo-align" computes +; a transformation matrix such that point p1 gets mapped to (0,0,0), p2 gets +; mapped to the Y axis and p3 gets mapped to the YZ plane. + +(define (tfo-align p1 p2 p3) + (let* ((x1 (pt-x p1)) (y1 (pt-y p1)) (z1 (pt-z p1)) + (x3 (pt-x p3)) (y3 (pt-y p3)) (z3 (pt-z p3)) + (x31 (FLOAT- x3 x1)) (y31 (FLOAT- y3 y1)) (z31 (FLOAT- z3 z1)) + (rotpY (pt-sub p2 p1)) + (Phi (pt-phi rotpY)) + (Theta (pt-theta rotpY)) + (sinP (FLOATsin Phi)) + (sinT (FLOATsin Theta)) + (cosP (FLOATcos Phi)) + (cosT (FLOATcos Theta)) + (sinPsinT (FLOAT* sinP sinT)) + (sinPcosT (FLOAT* sinP cosT)) + (cosPsinT (FLOAT* cosP sinT)) + (cosPcosT (FLOAT* cosP cosT)) + (rotpZ + (make-pt + (FLOAT- (FLOAT* cosT x31) + (FLOAT* sinT z31)) + (FLOAT+ (FLOAT* sinPsinT x31) + (FLOAT* cosP y31) + (FLOAT* sinPcosT z31)) + (FLOAT+ (FLOAT* cosPsinT x31) + (FLOAT- (FLOAT* sinP y31)) + (FLOAT* cosPcosT z31)))) + (Rho (pt-theta rotpZ)) + (cosR (FLOATcos Rho)) + (sinR (FLOATsin Rho)) + (x (FLOAT+ (FLOAT- (FLOAT* x1 cosT)) + (FLOAT* z1 sinT))) + (y (FLOAT- (FLOAT- (FLOAT- (FLOAT* x1 sinPsinT)) + (FLOAT* y1 cosP)) + (FLOAT* z1 sinPcosT))) + (z (FLOAT- (FLOAT+ (FLOAT- (FLOAT* x1 cosPsinT)) + (FLOAT* y1 sinP)) + (FLOAT* z1 cosPcosT)))) + (make-tfo + (FLOAT- (FLOAT* cosT cosR) (FLOAT* cosPsinT sinR)) + sinPsinT + (FLOAT+ (FLOAT* cosT sinR) (FLOAT* cosPsinT cosR)) + (FLOAT* sinP sinR) + cosP + (FLOAT- (FLOAT* sinP cosR)) + (FLOAT- (FLOAT- (FLOAT* sinT cosR)) (FLOAT* cosPcosT sinR)) + sinPcosT + (FLOAT+ (FLOAT- (FLOAT* sinT sinR)) (FLOAT* cosPcosT cosR)) + (FLOAT- (FLOAT* x cosR) (FLOAT* z sinR)) + y + (FLOAT+ (FLOAT* x sinR) (FLOAT* z cosR))))) + +; -- NUCLEIC ACID CONFORMATIONS DATA BASE ------------------------------------- + +; Numbering of atoms follows the paper: +; +; IUPAC-IUB Joint Commission on Biochemical Nomenclature (JCBN) +; (1983) Abbreviations and Symbols for the Description of +; Conformations of Polynucleotide Chains. Eur. J. Biochem 131, +; 9-15. +; +; In the atom names, we have used "*" instead of "'". + +; Define part common to all 4 nucleotide types. + +(def-struct #f nuc + dgf-base-tfo ; defines the standard position for wc and wc-dumas + P-O3*-275-tfo ; defines the standard position for the connect function + P-O3*-180-tfo + P-O3*-60-tfo + P O1P O2P O5* C5* H5* H5** C4* H4* O4* C1* H1* C2* H2** O2* H2* C3* + H3* O3* N1 N3 C2 C4 C5 C6) + +; Define remaining atoms for each nucleotide type. + +(def-nuc #t rA N6 N7 N9 C8 H2 H61 H62 H8) +(def-nuc #t rC N4 O2 H41 H42 H5 H6) +(def-nuc #t rG N2 N7 N9 C8 O6 H1 H21 H22 H8) +(def-nuc #t rU O2 O4 H3 H5 H6) + +; Database of nucleotide conformations: + +(define rA + (make-constant-rA + #( -0.0018 -0.8207 0.5714 ; dgf-base-tfo + 0.2679 -0.5509 -0.7904 + 0.9634 0.1517 0.2209 + 0.0073 8.4030 0.6232) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4550 8.2120 -2.8810) ; C5* + #( 5.4546 8.8508 -1.9978) ; H5* + #( 5.7588 8.6625 -3.8259) ; H5** + #( 6.4970 7.1480 -2.5980) ; C4* + #( 7.4896 7.5919 -2.5214) ; H4* + #( 6.1630 6.4860 -1.3440) ; O4* + #( 6.5400 5.1200 -1.4190) ; C1* + #( 7.2763 4.9681 -0.6297) ; H1* + #( 7.1940 4.8830 -2.7770) ; C2* + #( 6.8667 3.9183 -3.1647) ; H2** + #( 8.5860 5.0910 -2.6140) ; O2* + #( 8.9510 4.7626 -1.7890) ; H2* + #( 6.5720 6.0040 -3.6090) ; C3* + #( 5.5636 5.7066 -3.8966) ; H3* + #( 7.3801 6.3562 -4.7350) ; O3* + #( 4.7150 0.4910 -0.1360) ; N1 + #( 6.3490 2.1730 -0.6020) ; N3 + #( 5.9530 0.9650 -0.2670) ; C2 + #( 5.2900 2.9790 -0.8260) ; C4 + #( 3.9720 2.6390 -0.7330) ; C5 + #( 3.6770 1.3160 -0.3660) ; C6 + #( 2.4280 0.8450 -0.2360) ; N6 + #( 3.1660 3.7290 -1.0360) ; N7 + #( 5.3170 4.2990 -1.1930) ; N9 + #( 4.0100 4.6780 -1.2990) ; C8 + #( 6.6890 0.1903 -0.0518) ; H2 + #( 1.6470 1.4460 -0.4040) ; H61 + #( 2.2780 -0.1080 -0.0280) ; H62 + #( 3.4421 5.5744 -1.5482) ; H8 + )) + +(define rA01 + (make-constant-rA + #( -0.0043 -0.8175 0.5759 ; dgf-base-tfo + 0.2617 -0.5567 -0.7884 + 0.9651 0.1473 0.2164 + 0.0359 8.3929 0.5532) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4352 8.2183 -2.7757) ; C5* + #( 5.3830 8.7883 -1.8481) ; H5* + #( 5.7729 8.7436 -3.6691) ; H5** + #( 6.4830 7.1518 -2.5252) ; C4* + #( 7.4749 7.5972 -2.4482) ; H4* + #( 6.1626 6.4620 -1.2827) ; O4* + #( 6.5431 5.0992 -1.3905) ; C1* + #( 7.2871 4.9328 -0.6114) ; H1* + #( 7.1852 4.8935 -2.7592) ; C2* + #( 6.8573 3.9363 -3.1645) ; H2** + #( 8.5780 5.1025 -2.6046) ; O2* + #( 8.9516 4.7577 -1.7902) ; H2* + #( 6.5522 6.0300 -3.5612) ; C3* + #( 5.5420 5.7356 -3.8459) ; H3* + #( 7.3487 6.4089 -4.6867) ; O3* + #( 4.7442 0.4514 -0.1390) ; N1 + #( 6.3687 2.1459 -0.5926) ; N3 + #( 5.9795 0.9335 -0.2657) ; C2 + #( 5.3052 2.9471 -0.8125) ; C4 + #( 3.9891 2.5987 -0.7230) ; C5 + #( 3.7016 1.2717 -0.3647) ; C6 + #( 2.4553 0.7925 -0.2390) ; N6 + #( 3.1770 3.6859 -1.0198) ; N7 + #( 5.3247 4.2695 -1.1710) ; N9 + #( 4.0156 4.6415 -1.2759) ; C8 + #( 6.7198 0.1618 -0.0547) ; H2 + #( 1.6709 1.3900 -0.4039) ; H61 + #( 2.3107 -0.1627 -0.0373) ; H62 + #( 3.4426 5.5361 -1.5199) ; H8 + )) + +(define rA02 + (make-constant-rA + #( 0.5566 0.0449 0.8296 ; dgf-base-tfo + 0.5125 0.7673 -0.3854 + -0.6538 0.6397 0.4041 + -9.1161 -3.7679 -2.9968) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.5778 6.6594 -4.0364) ; C5* + #( 4.9220 7.1963 -4.9204) ; H5* + #( 3.7996 5.9091 -4.1764) ; H5** + #( 5.7873 5.8869 -3.5482) ; C4* + #( 6.0405 5.0875 -4.2446) ; H4* + #( 6.9135 6.8036 -3.4310) ; O4* + #( 7.7293 6.4084 -2.3392) ; C1* + #( 8.7078 6.1815 -2.7624) ; H1* + #( 7.1305 5.1418 -1.7347) ; C2* + #( 7.2040 5.1982 -0.6486) ; H2** + #( 7.7417 4.0392 -2.3813) ; O2* + #( 8.6785 4.1443 -2.5630) ; H2* + #( 5.6666 5.2728 -2.1536) ; C3* + #( 5.1747 5.9805 -1.4863) ; H3* + #( 4.9997 4.0086 -2.1973) ; O3* + #( 10.3245 8.5459 1.5467) ; N1 + #( 9.8051 6.9432 -0.1497) ; N3 + #( 10.5175 7.4328 0.8408) ; C2 + #( 8.7523 7.7422 -0.4228) ; C4 + #( 8.4257 8.9060 0.2099) ; C5 + #( 9.2665 9.3242 1.2540) ; C6 + #( 9.0664 10.4462 1.9610) ; N6 + #( 7.2750 9.4537 -0.3428) ; N7 + #( 7.7962 7.5519 -1.3859) ; N9 + #( 6.9479 8.6157 -1.2771) ; C8 + #( 11.4063 6.9047 1.1859) ; H2 + #( 8.2845 11.0341 1.7552) ; H61 + #( 9.6584 10.6647 2.7198) ; H62 + #( 6.0430 8.9853 -1.7594) ; H8 + )) + +(define rA03 + (make-constant-rA + #( -0.5021 0.0731 0.8617 ; dgf-base-tfo + -0.8112 0.3054 -0.4986 + -0.2996 -0.9494 -0.0940 + 6.4273 -5.1944 -3.7807) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.1214 6.7116 -1.9049) ; C5* + #( 3.3465 5.9610 -2.0607) ; H5* + #( 4.0789 7.2928 -0.9837) ; H5** + #( 5.4170 5.9293 -1.8186) ; C4* + #( 5.4506 5.3400 -0.9023) ; H4* + #( 5.5067 5.0417 -2.9703) ; O4* + #( 6.8650 4.9152 -3.3612) ; C1* + #( 7.1090 3.8577 -3.2603) ; H1* + #( 7.7152 5.7282 -2.3894) ; C2* + #( 8.5029 6.2356 -2.9463) ; H2** + #( 8.1036 4.8568 -1.3419) ; O2* + #( 8.3270 3.9651 -1.6184) ; H2* + #( 6.7003 6.7565 -1.8911) ; C3* + #( 6.5898 7.5329 -2.6482) ; H3* + #( 7.0505 7.2878 -0.6105) ; O3* + #( 9.6740 4.7656 -7.6614) ; N1 + #( 9.0739 4.3013 -5.3941) ; N3 + #( 9.8416 4.2192 -6.4581) ; C2 + #( 7.9885 5.0632 -5.6446) ; C4 + #( 7.6822 5.6856 -6.8194) ; C5 + #( 8.5831 5.5215 -7.8840) ; C6 + #( 8.4084 6.0747 -9.0933) ; N6 + #( 6.4857 6.3816 -6.7035) ; N7 + #( 6.9740 5.3703 -4.7760) ; N9 + #( 6.1133 6.1613 -5.4808) ; C8 + #( 10.7627 3.6375 -6.4220) ; H2 + #( 7.6031 6.6390 -9.2733) ; H61 + #( 9.1004 5.9708 -9.7893) ; H62 + #( 5.1705 6.6830 -5.3167) ; H8 + )) + +(define rA04 + (make-constant-rA + #( -0.5426 -0.8175 0.1929 ; dgf-base-tfo + 0.8304 -0.5567 -0.0237 + 0.1267 0.1473 0.9809 + -0.5075 8.3929 0.2229) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4352 8.2183 -2.7757) ; C5* + #( 5.3830 8.7883 -1.8481) ; H5* + #( 5.7729 8.7436 -3.6691) ; H5** + #( 6.4830 7.1518 -2.5252) ; C4* + #( 7.4749 7.5972 -2.4482) ; H4* + #( 6.1626 6.4620 -1.2827) ; O4* + #( 6.5431 5.0992 -1.3905) ; C1* + #( 7.2871 4.9328 -0.6114) ; H1* + #( 7.1852 4.8935 -2.7592) ; C2* + #( 6.8573 3.9363 -3.1645) ; H2** + #( 8.5780 5.1025 -2.6046) ; O2* + #( 8.9516 4.7577 -1.7902) ; H2* + #( 6.5522 6.0300 -3.5612) ; C3* + #( 5.5420 5.7356 -3.8459) ; H3* + #( 7.3487 6.4089 -4.6867) ; O3* + #( 3.6343 2.6680 2.0783) ; N1 + #( 5.4505 3.9805 1.2446) ; N3 + #( 4.7540 3.3816 2.1851) ; C2 + #( 4.8805 3.7951 0.0354) ; C4 + #( 3.7416 3.0925 -0.2305) ; C5 + #( 3.0873 2.4980 0.8606) ; C6 + #( 1.9600 1.7805 0.7462) ; N6 + #( 3.4605 3.1184 -1.5906) ; N7 + #( 5.3247 4.2695 -1.1710) ; N9 + #( 4.4244 3.8244 -2.0953) ; C8 + #( 5.0814 3.4352 3.2234) ; H2 + #( 1.5423 1.6454 -0.1520) ; H61 + #( 1.5716 1.3398 1.5392) ; H62 + #( 4.2675 3.8876 -3.1721) ; H8 + )) + +(define rA05 + (make-constant-rA + #( -0.5891 0.0449 0.8068 ; dgf-base-tfo + 0.5375 0.7673 0.3498 + -0.6034 0.6397 -0.4762 + -0.3019 -3.7679 -9.5913) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.5778 6.6594 -4.0364) ; C5* + #( 4.9220 7.1963 -4.9204) ; H5* + #( 3.7996 5.9091 -4.1764) ; H5** + #( 5.7873 5.8869 -3.5482) ; C4* + #( 6.0405 5.0875 -4.2446) ; H4* + #( 6.9135 6.8036 -3.4310) ; O4* + #( 7.7293 6.4084 -2.3392) ; C1* + #( 8.7078 6.1815 -2.7624) ; H1* + #( 7.1305 5.1418 -1.7347) ; C2* + #( 7.2040 5.1982 -0.6486) ; H2** + #( 7.7417 4.0392 -2.3813) ; O2* + #( 8.6785 4.1443 -2.5630) ; H2* + #( 5.6666 5.2728 -2.1536) ; C3* + #( 5.1747 5.9805 -1.4863) ; H3* + #( 4.9997 4.0086 -2.1973) ; O3* + #( 10.2594 10.6774 -1.0056) ; N1 + #( 9.7528 8.7080 -2.2631) ; N3 + #( 10.4471 9.7876 -1.9791) ; C2 + #( 8.7271 8.5575 -1.3991) ; C4 + #( 8.4100 9.3803 -0.3580) ; C5 + #( 9.2294 10.5030 -0.1574) ; C6 + #( 9.0349 11.3951 0.8250) ; N6 + #( 7.2891 8.9068 0.3121) ; N7 + #( 7.7962 7.5519 -1.3859) ; N9 + #( 6.9702 7.8292 -0.3353) ; C8 + #( 11.3132 10.0537 -2.5851) ; H2 + #( 8.2741 11.2784 1.4629) ; H61 + #( 9.6733 12.1368 0.9529) ; H62 + #( 6.0888 7.3990 0.1403) ; H8 + )) + +(define rA06 + (make-constant-rA + #( -0.9815 0.0731 -0.1772 ; dgf-base-tfo + 0.1912 0.3054 -0.9328 + -0.0141 -0.9494 -0.3137 + 5.7506 -5.1944 4.7470) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.1214 6.7116 -1.9049) ; C5* + #( 3.3465 5.9610 -2.0607) ; H5* + #( 4.0789 7.2928 -0.9837) ; H5** + #( 5.4170 5.9293 -1.8186) ; C4* + #( 5.4506 5.3400 -0.9023) ; H4* + #( 5.5067 5.0417 -2.9703) ; O4* + #( 6.8650 4.9152 -3.3612) ; C1* + #( 7.1090 3.8577 -3.2603) ; H1* + #( 7.7152 5.7282 -2.3894) ; C2* + #( 8.5029 6.2356 -2.9463) ; H2** + #( 8.1036 4.8568 -1.3419) ; O2* + #( 8.3270 3.9651 -1.6184) ; H2* + #( 6.7003 6.7565 -1.8911) ; C3* + #( 6.5898 7.5329 -2.6482) ; H3* + #( 7.0505 7.2878 -0.6105) ; O3* + #( 6.6624 3.5061 -8.2986) ; N1 + #( 6.5810 3.2570 -5.9221) ; N3 + #( 6.5151 2.8263 -7.1625) ; C2 + #( 6.8364 4.5817 -5.8882) ; C4 + #( 7.0116 5.4064 -6.9609) ; C5 + #( 6.9173 4.8260 -8.2361) ; C6 + #( 7.0668 5.5163 -9.3763) ; N6 + #( 7.2573 6.7070 -6.5394) ; N7 + #( 6.9740 5.3703 -4.7760) ; N9 + #( 7.2238 6.6275 -5.2453) ; C8 + #( 6.3146 1.7741 -7.3641) ; H2 + #( 7.2568 6.4972 -9.3456) ; H61 + #( 7.0437 5.0478 -10.2446) ; H62 + #( 7.4108 7.6227 -4.8418) ; H8 + )) + +(define rA07 + (make-constant-rA + #( 0.2379 0.1310 -0.9624 ; dgf-base-tfo + -0.5876 -0.7696 -0.2499 + -0.7734 0.6249 -0.1061 + 30.9870 -26.9344 42.6416) + #( 0.7529 0.1548 0.6397 ; P-O3*-275-tfo + 0.2952 -0.9481 -0.1180 + 0.5882 0.2777 -0.7595 + -58.8919 -11.3095 6.0866) + #( -0.0239 0.9667 -0.2546 ; P-O3*-180-tfo + 0.9731 -0.0359 -0.2275 + -0.2290 -0.2532 -0.9399 + 3.5401 -29.7913 52.2796) + #( -0.8912 -0.4531 0.0242 ; P-O3*-60-tfo + -0.1183 0.1805 -0.9764 + 0.4380 -0.8730 -0.2145 + 19.9023 54.8054 15.2799) + #( 41.8210 8.3880 43.5890) ; P + #( 42.5400 8.0450 44.8330) ; O1P + #( 42.2470 9.6920 42.9910) ; O2P + #( 40.2550 8.2030 43.7340) ; O5* + #( 39.3505 8.4697 42.6565) ; C5* + #( 39.1377 7.5433 42.1230) ; H5* + #( 39.7203 9.3119 42.0717) ; H5** + #( 38.0405 8.9195 43.2869) ; C4* + #( 37.3687 9.3036 42.5193) ; H4* + #( 37.4319 7.8146 43.9387) ; O4* + #( 37.1959 8.1354 45.3237) ; C1* + #( 36.1788 8.5202 45.3970) ; H1* + #( 38.1721 9.2328 45.6504) ; C2* + #( 39.1555 8.7939 45.8188) ; H2** + #( 37.7862 10.0617 46.7013) ; O2* + #( 37.3087 9.6229 47.4092) ; H2* + #( 38.1844 10.0268 44.3367) ; C3* + #( 39.1578 10.5054 44.2289) ; H3* + #( 37.0547 10.9127 44.3441) ; O3* + #( 34.8811 4.2072 47.5784) ; N1 + #( 35.1084 6.1336 46.1818) ; N3 + #( 34.4108 5.1360 46.7207) ; C2 + #( 36.3908 6.1224 46.6053) ; C4 + #( 36.9819 5.2334 47.4697) ; C5 + #( 36.1786 4.1985 48.0035) ; C6 + #( 36.6103 3.2749 48.8452) ; N6 + #( 38.3236 5.5522 47.6595) ; N7 + #( 37.3887 7.0024 46.2437) ; N9 + #( 38.5055 6.6096 46.9057) ; C8 + #( 33.3553 5.0152 46.4771) ; H2 + #( 37.5730 3.2804 49.1507) ; H61 + #( 35.9775 2.5638 49.1828) ; H62 + #( 39.5461 6.9184 47.0041) ; H8 + )) + +(define rA08 + (make-constant-rA + #( 0.1084 -0.0895 -0.9901 ; dgf-base-tfo + 0.9789 -0.1638 0.1220 + -0.1731 -0.9824 0.0698 + -2.9039 47.2655 33.0094) + #( 0.7529 0.1548 0.6397 ; P-O3*-275-tfo + 0.2952 -0.9481 -0.1180 + 0.5882 0.2777 -0.7595 + -58.8919 -11.3095 6.0866) + #( -0.0239 0.9667 -0.2546 ; P-O3*-180-tfo + 0.9731 -0.0359 -0.2275 + -0.2290 -0.2532 -0.9399 + 3.5401 -29.7913 52.2796) + #( -0.8912 -0.4531 0.0242 ; P-O3*-60-tfo + -0.1183 0.1805 -0.9764 + 0.4380 -0.8730 -0.2145 + 19.9023 54.8054 15.2799) + #( 41.8210 8.3880 43.5890) ; P + #( 42.5400 8.0450 44.8330) ; O1P + #( 42.2470 9.6920 42.9910) ; O2P + #( 40.2550 8.2030 43.7340) ; O5* + #( 39.4850 8.9301 44.6977) ; C5* + #( 39.0638 9.8199 44.2296) ; H5* + #( 40.0757 9.0713 45.6029) ; H5** + #( 38.3102 8.0414 45.0789) ; C4* + #( 37.7842 8.4637 45.9351) ; H4* + #( 37.4200 7.9453 43.9769) ; O4* + #( 37.2249 6.5609 43.6273) ; C1* + #( 36.3360 6.2168 44.1561) ; H1* + #( 38.4347 5.8414 44.1590) ; C2* + #( 39.2688 5.9974 43.4749) ; H2** + #( 38.2344 4.4907 44.4348) ; O2* + #( 37.6374 4.0386 43.8341) ; H2* + #( 38.6926 6.6079 45.4637) ; C3* + #( 39.7585 6.5640 45.6877) ; H3* + #( 37.8238 6.0705 46.4723) ; O3* + #( 33.9162 6.2598 39.7758) ; N1 + #( 34.6709 6.5759 42.0215) ; N3 + #( 33.7257 6.5186 41.0858) ; C2 + #( 35.8935 6.3324 41.5018) ; C4 + #( 36.2105 6.0601 40.1932) ; C5 + #( 35.1538 6.0151 39.2537) ; C6 + #( 35.3088 5.7642 37.9649) ; N6 + #( 37.5818 5.8677 40.0507) ; N7 + #( 37.0932 6.3197 42.1810) ; N9 + #( 38.0509 6.0354 41.2635) ; C8 + #( 32.6830 6.6898 41.3532) ; H2 + #( 36.2305 5.5855 37.5925) ; H61 + #( 34.5056 5.7512 37.3528) ; H62 + #( 39.1318 5.8993 41.2285) ; H8 + )) + +(define rA09 + (make-constant-rA + #( 0.8467 0.4166 -0.3311 ; dgf-base-tfo + -0.3962 0.9089 0.1303 + 0.3552 0.0209 0.9346 + -42.7319 -26.6223 -29.8163) + #( 0.7529 0.1548 0.6397 ; P-O3*-275-tfo + 0.2952 -0.9481 -0.1180 + 0.5882 0.2777 -0.7595 + -58.8919 -11.3095 6.0866) + #( -0.0239 0.9667 -0.2546 ; P-O3*-180-tfo + 0.9731 -0.0359 -0.2275 + -0.2290 -0.2532 -0.9399 + 3.5401 -29.7913 52.2796) + #( -0.8912 -0.4531 0.0242 ; P-O3*-60-tfo + -0.1183 0.1805 -0.9764 + 0.4380 -0.8730 -0.2145 + 19.9023 54.8054 15.2799) + #( 41.8210 8.3880 43.5890) ; P + #( 42.5400 8.0450 44.8330) ; O1P + #( 42.2470 9.6920 42.9910) ; O2P + #( 40.2550 8.2030 43.7340) ; O5* + #( 39.3505 8.4697 42.6565) ; C5* + #( 39.1377 7.5433 42.1230) ; H5* + #( 39.7203 9.3119 42.0717) ; H5** + #( 38.0405 8.9195 43.2869) ; C4* + #( 37.6479 8.1347 43.9335) ; H4* + #( 38.2691 10.0933 44.0524) ; O4* + #( 37.3999 11.1488 43.5973) ; C1* + #( 36.5061 11.1221 44.2206) ; H1* + #( 37.0364 10.7838 42.1836) ; C2* + #( 37.8636 11.0489 41.5252) ; H2** + #( 35.8275 11.3133 41.7379) ; O2* + #( 35.6214 12.1896 42.0714) ; H2* + #( 36.9316 9.2556 42.2837) ; C3* + #( 37.1778 8.8260 41.3127) ; H3* + #( 35.6285 8.9334 42.7926) ; O3* + #( 38.1482 15.2833 46.4641) ; N1 + #( 37.3641 13.0968 45.9007) ; N3 + #( 37.5032 14.1288 46.7300) ; C2 + #( 37.9570 13.3377 44.7113) ; C4 + #( 38.6397 14.4660 44.3267) ; C5 + #( 38.7473 15.5229 45.2609) ; C6 + #( 39.3720 16.6649 45.0297) ; N6 + #( 39.1079 14.3351 43.0223) ; N7 + #( 38.0132 12.4868 43.6280) ; N9 + #( 38.7058 13.1402 42.6620) ; C8 + #( 37.0731 14.0857 47.7306) ; H2 + #( 39.8113 16.8281 44.1350) ; H61 + #( 39.4100 17.3741 45.7478) ; H62 + #( 39.0412 12.9660 41.6397) ; H8 + )) + +(define rA10 + (make-constant-rA + #( 0.7063 0.6317 -0.3196 ; dgf-base-tfo + -0.0403 -0.4149 -0.9090 + -0.7068 0.6549 -0.2676 + 6.4402 -52.1496 30.8246) + #( 0.7529 0.1548 0.6397 ; P-O3*-275-tfo + 0.2952 -0.9481 -0.1180 + 0.5882 0.2777 -0.7595 + -58.8919 -11.3095 6.0866) + #( -0.0239 0.9667 -0.2546 ; P-O3*-180-tfo + 0.9731 -0.0359 -0.2275 + -0.2290 -0.2532 -0.9399 + 3.5401 -29.7913 52.2796) + #( -0.8912 -0.4531 0.0242 ; P-O3*-60-tfo + -0.1183 0.1805 -0.9764 + 0.4380 -0.8730 -0.2145 + 19.9023 54.8054 15.2799) + #( 41.8210 8.3880 43.5890) ; P + #( 42.5400 8.0450 44.8330) ; O1P + #( 42.2470 9.6920 42.9910) ; O2P + #( 40.2550 8.2030 43.7340) ; O5* + #( 39.4850 8.9301 44.6977) ; C5* + #( 39.0638 9.8199 44.2296) ; H5* + #( 40.0757 9.0713 45.6029) ; H5** + #( 38.3102 8.0414 45.0789) ; C4* + #( 37.7099 7.8166 44.1973) ; H4* + #( 38.8012 6.8321 45.6380) ; O4* + #( 38.2431 6.6413 46.9529) ; C1* + #( 37.3505 6.0262 46.8385) ; H1* + #( 37.8484 8.0156 47.4214) ; C2* + #( 38.7381 8.5406 47.7690) ; H2** + #( 36.8286 8.0368 48.3701) ; O2* + #( 36.8392 7.3063 48.9929) ; H2* + #( 37.3576 8.6512 46.1132) ; C3* + #( 37.5207 9.7275 46.1671) ; H3* + #( 35.9985 8.2392 45.9032) ; O3* + #( 39.9117 2.2278 48.8527) ; N1 + #( 38.6207 3.6941 47.4757) ; N3 + #( 38.9872 2.4888 47.9057) ; C2 + #( 39.2961 4.6720 48.1174) ; C4 + #( 40.2546 4.5307 49.0912) ; C5 + #( 40.5932 3.2189 49.4985) ; C6 + #( 41.4938 2.9317 50.4229) ; N6 + #( 40.7195 5.7755 49.5060) ; N7 + #( 39.1730 6.0305 47.9170) ; N9 + #( 40.0413 6.6250 48.7728) ; C8 + #( 38.5257 1.5960 47.4838) ; H2 + #( 41.9907 3.6753 50.8921) ; H61 + #( 41.6848 1.9687 50.6599) ; H62 + #( 40.3571 7.6321 49.0452) ; H8 + )) + +(define rAs + (list rA01 rA02 rA03 rA04 rA05 rA06 rA07 rA08 rA09 rA10)) + +(define rC + (make-constant-rC + #( -0.0359 -0.8071 0.5894 ; dgf-base-tfo + -0.2669 0.5761 0.7726 + -0.9631 -0.1296 -0.2361 + 0.1584 8.3434 0.5434) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2430 -8.2420 2.8260) ; C5* + #( 5.1974 -8.8497 1.9223) ; H5* + #( 5.5548 -8.7348 3.7469) ; H5** + #( 6.3140 -7.2060 2.5510) ; C4* + #( 7.2954 -7.6762 2.4898) ; H4* + #( 6.0140 -6.5420 1.2890) ; O4* + #( 6.4190 -5.1840 1.3620) ; C1* + #( 7.1608 -5.0495 0.5747) ; H1* + #( 7.0760 -4.9560 2.7270) ; C2* + #( 6.7770 -3.9803 3.1099) ; H2** + #( 8.4500 -5.1930 2.5810) ; O2* + #( 8.8309 -4.8755 1.7590) ; H2* + #( 6.4060 -6.0590 3.5580) ; C3* + #( 5.4021 -5.7313 3.8281) ; H3* + #( 7.1570 -6.4240 4.7070) ; O3* + #( 5.2170 -4.3260 1.1690) ; N1 + #( 4.2960 -2.2560 0.6290) ; N3 + #( 5.4330 -3.0200 0.7990) ; C2 + #( 2.9930 -2.6780 0.7940) ; C4 + #( 2.8670 -4.0630 1.1830) ; C5 + #( 3.9570 -4.8300 1.3550) ; C6 + #( 2.0187 -1.8047 0.5874) ; N4 + #( 6.5470 -2.5560 0.6290) ; O2 + #( 1.0684 -2.1236 0.7109) ; H41 + #( 2.2344 -0.8560 0.3162) ; H42 + #( 1.8797 -4.4972 1.3404) ; H5 + #( 3.8479 -5.8742 1.6480) ; H6 + )) + +(define rC01 + (make-constant-rC + #( -0.0137 -0.8012 0.5983 ; dgf-base-tfo + -0.2523 0.5817 0.7733 + -0.9675 -0.1404 -0.2101 + 0.2031 8.3874 0.4228) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2416 -8.2422 2.8181) ; C5* + #( 5.2050 -8.8128 1.8901) ; H5* + #( 5.5368 -8.7738 3.7227) ; H5** + #( 6.3232 -7.2037 2.6002) ; C4* + #( 7.3048 -7.6757 2.5577) ; H4* + #( 6.0635 -6.5092 1.3456) ; O4* + #( 6.4697 -5.1547 1.4629) ; C1* + #( 7.2354 -5.0043 0.7018) ; H1* + #( 7.0856 -4.9610 2.8521) ; C2* + #( 6.7777 -3.9935 3.2487) ; H2** + #( 8.4627 -5.1992 2.7423) ; O2* + #( 8.8693 -4.8638 1.9399) ; H2* + #( 6.3877 -6.0809 3.6362) ; C3* + #( 5.3770 -5.7562 3.8834) ; H3* + #( 7.1024 -6.4754 4.7985) ; O3* + #( 5.2764 -4.2883 1.2538) ; N1 + #( 4.3777 -2.2062 0.7229) ; N3 + #( 5.5069 -2.9779 0.9088) ; C2 + #( 3.0693 -2.6246 0.8500) ; C4 + #( 2.9279 -4.0146 1.2149) ; C5 + #( 4.0101 -4.7892 1.4017) ; C6 + #( 2.1040 -1.7437 0.6331) ; N4 + #( 6.6267 -2.5166 0.7728) ; O2 + #( 1.1496 -2.0600 0.7287) ; H41 + #( 2.3303 -0.7921 0.3815) ; H42 + #( 1.9353 -4.4465 1.3419) ; H5 + #( 3.8895 -5.8371 1.6762) ; H6 + )) + +(define rC02 + (make-constant-rC + #( 0.5141 0.0246 0.8574 ; dgf-base-tfo + -0.5547 -0.7529 0.3542 + 0.6542 -0.6577 -0.3734 + -9.1111 -3.4598 -3.2939) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 4.3825 -6.6585 4.0489) ; C5* + #( 4.6841 -7.2019 4.9443) ; H5* + #( 3.6189 -5.8889 4.1625) ; H5** + #( 5.6255 -5.9175 3.5998) ; C4* + #( 5.8732 -5.1228 4.3034) ; H4* + #( 6.7337 -6.8605 3.5222) ; O4* + #( 7.5932 -6.4923 2.4548) ; C1* + #( 8.5661 -6.2983 2.9064) ; H1* + #( 7.0527 -5.2012 1.8322) ; C2* + #( 7.1627 -5.2525 0.7490) ; H2** + #( 7.6666 -4.1249 2.4880) ; O2* + #( 8.5944 -4.2543 2.6981) ; H2* + #( 5.5661 -5.3029 2.2009) ; C3* + #( 5.0841 -6.0018 1.5172) ; H3* + #( 4.9062 -4.0452 2.2042) ; O3* + #( 7.6298 -7.6136 1.4752) ; N1 + #( 8.6945 -8.7046 -0.2857) ; N3 + #( 8.6943 -7.6514 0.6066) ; C2 + #( 7.7426 -9.6987 -0.3801) ; C4 + #( 6.6642 -9.5742 0.5722) ; C5 + #( 6.6391 -8.5592 1.4526) ; C6 + #( 7.9033 -10.6371 -1.3010) ; N4 + #( 9.5840 -6.8186 0.6136) ; O2 + #( 7.2009 -11.3604 -1.3619) ; H41 + #( 8.7058 -10.6168 -1.9140) ; H42 + #( 5.8585 -10.3083 0.5822) ; H5 + #( 5.8197 -8.4773 2.1667) ; H6 + )) + +(define rC03 + (make-constant-rC + #( -0.4993 0.0476 0.8651 ; dgf-base-tfo + 0.8078 -0.3353 0.4847 + 0.3132 0.9409 0.1290 + 6.2989 -5.2303 -3.8577) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 3.9938 -6.7042 1.9023) ; C5* + #( 3.2332 -5.9343 2.0319) ; H5* + #( 3.9666 -7.2863 0.9812) ; H5** + #( 5.3098 -5.9546 1.8564) ; C4* + #( 5.3863 -5.3702 0.9395) ; H4* + #( 5.3851 -5.0642 3.0076) ; O4* + #( 6.7315 -4.9724 3.4462) ; C1* + #( 7.0033 -3.9202 3.3619) ; H1* + #( 7.5997 -5.8018 2.4948) ; C2* + #( 8.3627 -6.3254 3.0707) ; H2** + #( 8.0410 -4.9501 1.4724) ; O2* + #( 8.2781 -4.0644 1.7570) ; H2* + #( 6.5701 -6.8129 1.9714) ; C3* + #( 6.4186 -7.5809 2.7299) ; H3* + #( 6.9357 -7.3841 0.7235) ; O3* + #( 6.8024 -5.4718 4.8475) ; N1 + #( 7.9218 -5.5700 6.8877) ; N3 + #( 7.8908 -5.0886 5.5944) ; C2 + #( 6.9789 -6.3827 7.4823) ; C4 + #( 5.8742 -6.7319 6.6202) ; C5 + #( 5.8182 -6.2769 5.3570) ; C6 + #( 7.1702 -6.7511 8.7402) ; N4 + #( 8.7747 -4.3728 5.1568) ; O2 + #( 6.4741 -7.3461 9.1662) ; H41 + #( 7.9889 -6.4396 9.2429) ; H42 + #( 5.0736 -7.3713 6.9922) ; H5 + #( 4.9784 -6.5473 4.7170) ; H6 + )) + +(define rC04 + (make-constant-rC + #( -0.5669 -0.8012 0.1918 ; dgf-base-tfo + -0.8129 0.5817 0.0273 + -0.1334 -0.1404 -0.9811 + -0.3279 8.3874 0.3355) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2416 -8.2422 2.8181) ; C5* + #( 5.2050 -8.8128 1.8901) ; H5* + #( 5.5368 -8.7738 3.7227) ; H5** + #( 6.3232 -7.2037 2.6002) ; C4* + #( 7.3048 -7.6757 2.5577) ; H4* + #( 6.0635 -6.5092 1.3456) ; O4* + #( 6.4697 -5.1547 1.4629) ; C1* + #( 7.2354 -5.0043 0.7018) ; H1* + #( 7.0856 -4.9610 2.8521) ; C2* + #( 6.7777 -3.9935 3.2487) ; H2** + #( 8.4627 -5.1992 2.7423) ; O2* + #( 8.8693 -4.8638 1.9399) ; H2* + #( 6.3877 -6.0809 3.6362) ; C3* + #( 5.3770 -5.7562 3.8834) ; H3* + #( 7.1024 -6.4754 4.7985) ; O3* + #( 5.2764 -4.2883 1.2538) ; N1 + #( 3.8961 -3.0896 -0.1893) ; N3 + #( 5.0095 -3.8907 -0.0346) ; C2 + #( 3.0480 -2.6632 0.8116) ; C4 + #( 3.4093 -3.1310 2.1292) ; C5 + #( 4.4878 -3.9124 2.3088) ; C6 + #( 2.0216 -1.8941 0.4804) ; N4 + #( 5.7005 -4.2164 -0.9842) ; O2 + #( 1.4067 -1.5873 1.2205) ; H41 + #( 1.8721 -1.6319 -0.4835) ; H42 + #( 2.8048 -2.8507 2.9918) ; H5 + #( 4.7491 -4.2593 3.3085) ; H6 + )) + +(define rC05 + (make-constant-rC + #( -0.6298 0.0246 0.7763 ; dgf-base-tfo + -0.5226 -0.7529 -0.4001 + 0.5746 -0.6577 0.4870 + -0.0208 -3.4598 -9.6882) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 4.3825 -6.6585 4.0489) ; C5* + #( 4.6841 -7.2019 4.9443) ; H5* + #( 3.6189 -5.8889 4.1625) ; H5** + #( 5.6255 -5.9175 3.5998) ; C4* + #( 5.8732 -5.1228 4.3034) ; H4* + #( 6.7337 -6.8605 3.5222) ; O4* + #( 7.5932 -6.4923 2.4548) ; C1* + #( 8.5661 -6.2983 2.9064) ; H1* + #( 7.0527 -5.2012 1.8322) ; C2* + #( 7.1627 -5.2525 0.7490) ; H2** + #( 7.6666 -4.1249 2.4880) ; O2* + #( 8.5944 -4.2543 2.6981) ; H2* + #( 5.5661 -5.3029 2.2009) ; C3* + #( 5.0841 -6.0018 1.5172) ; H3* + #( 4.9062 -4.0452 2.2042) ; O3* + #( 7.6298 -7.6136 1.4752) ; N1 + #( 8.5977 -9.5977 0.7329) ; N3 + #( 8.5951 -8.5745 1.6594) ; C2 + #( 7.7372 -9.7371 -0.3364) ; C4 + #( 6.7596 -8.6801 -0.4476) ; C5 + #( 6.7338 -7.6721 0.4408) ; C6 + #( 7.8849 -10.7881 -1.1289) ; N4 + #( 9.3993 -8.5377 2.5743) ; O2 + #( 7.2499 -10.8809 -1.9088) ; H41 + #( 8.6122 -11.4649 -0.9468) ; H42 + #( 6.0317 -8.6941 -1.2588) ; H5 + #( 5.9901 -6.8809 0.3459) ; H6 + )) + +(define rC06 + (make-constant-rC + #( -0.9837 0.0476 -0.1733 ; dgf-base-tfo + -0.1792 -0.3353 0.9249 + -0.0141 0.9409 0.3384 + 5.7793 -5.2303 4.5997) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 3.9938 -6.7042 1.9023) ; C5* + #( 3.2332 -5.9343 2.0319) ; H5* + #( 3.9666 -7.2863 0.9812) ; H5** + #( 5.3098 -5.9546 1.8564) ; C4* + #( 5.3863 -5.3702 0.9395) ; H4* + #( 5.3851 -5.0642 3.0076) ; O4* + #( 6.7315 -4.9724 3.4462) ; C1* + #( 7.0033 -3.9202 3.3619) ; H1* + #( 7.5997 -5.8018 2.4948) ; C2* + #( 8.3627 -6.3254 3.0707) ; H2** + #( 8.0410 -4.9501 1.4724) ; O2* + #( 8.2781 -4.0644 1.7570) ; H2* + #( 6.5701 -6.8129 1.9714) ; C3* + #( 6.4186 -7.5809 2.7299) ; H3* + #( 6.9357 -7.3841 0.7235) ; O3* + #( 6.8024 -5.4718 4.8475) ; N1 + #( 6.6920 -5.0495 7.1354) ; N3 + #( 6.6201 -4.5500 5.8506) ; C2 + #( 6.9254 -6.3614 7.4926) ; C4 + #( 7.1046 -7.2543 6.3718) ; C5 + #( 7.0391 -6.7951 5.1106) ; C6 + #( 6.9614 -6.6648 8.7815) ; N4 + #( 6.4083 -3.3696 5.6340) ; O2 + #( 7.1329 -7.6280 9.0324) ; H41 + #( 6.8204 -5.9469 9.4777) ; H42 + #( 7.2954 -8.3135 6.5440) ; H5 + #( 7.1753 -7.4798 4.2735) ; H6 + )) + +(define rC07 + (make-constant-rC + #( 0.0033 0.2720 -0.9623 ; dgf-base-tfo + 0.3013 -0.9179 -0.2584 + -0.9535 -0.2891 -0.0850 + 43.0403 13.7233 34.5710) + #( 0.9187 0.2887 0.2694 ; P-O3*-275-tfo + 0.0302 -0.7316 0.6811 + 0.3938 -0.6176 -0.6808 + -48.4330 26.3254 13.6383) + #( -0.1504 0.7744 -0.6145 ; P-O3*-180-tfo + 0.7581 0.4893 0.4311 + 0.6345 -0.4010 -0.6607 + -31.9784 -13.4285 44.9650) + #( -0.6236 -0.7810 -0.0337 ; P-O3*-60-tfo + -0.6890 0.5694 -0.4484 + 0.3694 -0.2564 -0.8932 + 12.1105 30.8774 46.0946) + #( 33.3400 11.0980 46.1750) ; P + #( 34.5130 10.2320 46.4660) ; O1P + #( 33.4130 12.3960 46.9340) ; O2P + #( 31.9810 10.3390 46.4820) ; O5* + #( 30.8152 11.1619 46.2003) ; C5* + #( 30.4519 10.9454 45.1957) ; H5* + #( 31.0379 12.2016 46.4400) ; H5** + #( 29.7081 10.7448 47.1428) ; C4* + #( 28.8710 11.4416 47.0982) ; H4* + #( 29.2550 9.4394 46.8162) ; O4* + #( 29.3907 8.5625 47.9460) ; C1* + #( 28.4416 8.5669 48.4819) ; H1* + #( 30.4468 9.2031 48.7952) ; C2* + #( 31.4222 8.9651 48.3709) ; H2** + #( 30.3701 8.9157 50.1624) ; O2* + #( 30.0652 8.0304 50.3740) ; H2* + #( 30.1622 10.6879 48.6120) ; C3* + #( 31.0952 11.2399 48.7254) ; H3* + #( 29.1076 11.1535 49.4702) ; O3* + #( 29.7883 7.2209 47.5235) ; N1 + #( 29.1825 5.0438 46.8275) ; N3 + #( 28.8008 6.2912 47.2263) ; C2 + #( 30.4888 4.6890 46.7186) ; C4 + #( 31.5034 5.6405 47.0249) ; C5 + #( 31.1091 6.8691 47.4156) ; C6 + #( 30.8109 3.4584 46.3336) ; N4 + #( 27.6171 6.5989 47.3189) ; O2 + #( 31.7923 3.2301 46.2638) ; H41 + #( 30.0880 2.7857 46.1215) ; H42 + #( 32.5542 5.3634 46.9395) ; H5 + #( 31.8523 7.6279 47.6603) ; H6 + )) + +(define rC08 + (make-constant-rC + #( 0.0797 -0.6026 -0.7941 ; dgf-base-tfo + 0.7939 0.5201 -0.3150 + 0.6028 -0.6054 0.5198 + -36.8341 41.5293 1.6628) + #( 0.9187 0.2887 0.2694 ; P-O3*-275-tfo + 0.0302 -0.7316 0.6811 + 0.3938 -0.6176 -0.6808 + -48.4330 26.3254 13.6383) + #( -0.1504 0.7744 -0.6145 ; P-O3*-180-tfo + 0.7581 0.4893 0.4311 + 0.6345 -0.4010 -0.6607 + -31.9784 -13.4285 44.9650) + #( -0.6236 -0.7810 -0.0337 ; P-O3*-60-tfo + -0.6890 0.5694 -0.4484 + 0.3694 -0.2564 -0.8932 + 12.1105 30.8774 46.0946) + #( 33.3400 11.0980 46.1750) ; P + #( 34.5130 10.2320 46.4660) ; O1P + #( 33.4130 12.3960 46.9340) ; O2P + #( 31.9810 10.3390 46.4820) ; O5* + #( 31.8779 9.9369 47.8760) ; C5* + #( 31.3239 10.6931 48.4322) ; H5* + #( 32.8647 9.6624 48.2489) ; H5** + #( 31.0429 8.6773 47.9401) ; C4* + #( 31.0779 8.2331 48.9349) ; H4* + #( 29.6956 8.9669 47.5983) ; O4* + #( 29.2784 8.1700 46.4782) ; C1* + #( 28.8006 7.2731 46.8722) ; H1* + #( 30.5544 7.7940 45.7875) ; C2* + #( 30.8837 8.6410 45.1856) ; H2** + #( 30.5100 6.6007 45.0582) ; O2* + #( 29.6694 6.4168 44.6326) ; H2* + #( 31.5146 7.5954 46.9527) ; C3* + #( 32.5255 7.8261 46.6166) ; H3* + #( 31.3876 6.2951 47.5516) ; O3* + #( 28.3976 8.9302 45.5933) ; N1 + #( 26.2155 9.6135 44.9910) ; N3 + #( 27.0281 8.8961 45.8192) ; C2 + #( 26.7044 10.3489 43.9595) ; C4 + #( 28.1088 10.3837 43.7247) ; C5 + #( 28.8978 9.6708 44.5535) ; C6 + #( 25.8715 11.0249 43.1749) ; N4 + #( 26.5733 8.2371 46.7484) ; O2 + #( 26.2707 11.5609 42.4177) ; H41 + #( 24.8760 10.9939 43.3427) ; H42 + #( 28.5089 10.9722 42.8990) ; H5 + #( 29.9782 9.6687 44.4097) ; H6 + )) + +(define rC09 + (make-constant-rC + #( 0.8727 0.4760 -0.1091 ; dgf-base-tfo + -0.4188 0.6148 -0.6682 + -0.2510 0.6289 0.7359 + -8.1687 -52.0761 -25.0726) + #( 0.9187 0.2887 0.2694 ; P-O3*-275-tfo + 0.0302 -0.7316 0.6811 + 0.3938 -0.6176 -0.6808 + -48.4330 26.3254 13.6383) + #( -0.1504 0.7744 -0.6145 ; P-O3*-180-tfo + 0.7581 0.4893 0.4311 + 0.6345 -0.4010 -0.6607 + -31.9784 -13.4285 44.9650) + #( -0.6236 -0.7810 -0.0337 ; P-O3*-60-tfo + -0.6890 0.5694 -0.4484 + 0.3694 -0.2564 -0.8932 + 12.1105 30.8774 46.0946) + #( 33.3400 11.0980 46.1750) ; P + #( 34.5130 10.2320 46.4660) ; O1P + #( 33.4130 12.3960 46.9340) ; O2P + #( 31.9810 10.3390 46.4820) ; O5* + #( 30.8152 11.1619 46.2003) ; C5* + #( 30.4519 10.9454 45.1957) ; H5* + #( 31.0379 12.2016 46.4400) ; H5** + #( 29.7081 10.7448 47.1428) ; C4* + #( 29.4506 9.6945 47.0059) ; H4* + #( 30.1045 10.9634 48.4885) ; O4* + #( 29.1794 11.8418 49.1490) ; C1* + #( 28.4388 11.2210 49.6533) ; H1* + #( 28.5211 12.6008 48.0367) ; C2* + #( 29.1947 13.3949 47.7147) ; H2** + #( 27.2316 13.0683 48.3134) ; O2* + #( 27.0851 13.3391 49.2227) ; H2* + #( 28.4131 11.5507 46.9391) ; C3* + #( 28.4451 12.0512 45.9713) ; H3* + #( 27.2707 10.6955 47.1097) ; O3* + #( 29.8751 12.7405 50.0682) ; N1 + #( 30.7172 13.1841 52.2328) ; N3 + #( 30.0617 12.3404 51.3847) ; C2 + #( 31.1834 14.3941 51.8297) ; C4 + #( 30.9913 14.8074 50.4803) ; C5 + #( 30.3434 13.9610 49.6548) ; C6 + #( 31.8090 15.1847 52.6957) ; N4 + #( 29.6470 11.2494 51.7616) ; O2 + #( 32.1422 16.0774 52.3606) ; H41 + #( 31.9392 14.8893 53.6527) ; H42 + #( 31.3632 15.7771 50.1491) ; H5 + #( 30.1742 14.2374 48.6141) ; H6 + )) + +(define rC10 + (make-constant-rC + #( 0.1549 0.8710 -0.4663 ; dgf-base-tfo + 0.6768 -0.4374 -0.5921 + -0.7197 -0.2239 -0.6572 + 25.2447 -14.1920 50.3201) + #( 0.9187 0.2887 0.2694 ; P-O3*-275-tfo + 0.0302 -0.7316 0.6811 + 0.3938 -0.6176 -0.6808 + -48.4330 26.3254 13.6383) + #( -0.1504 0.7744 -0.6145 ; P-O3*-180-tfo + 0.7581 0.4893 0.4311 + 0.6345 -0.4010 -0.6607 + -31.9784 -13.4285 44.9650) + #( -0.6236 -0.7810 -0.0337 ; P-O3*-60-tfo + -0.6890 0.5694 -0.4484 + 0.3694 -0.2564 -0.8932 + 12.1105 30.8774 46.0946) + #( 33.3400 11.0980 46.1750) ; P + #( 34.5130 10.2320 46.4660) ; O1P + #( 33.4130 12.3960 46.9340) ; O2P + #( 31.9810 10.3390 46.4820) ; O5* + #( 31.8779 9.9369 47.8760) ; C5* + #( 31.3239 10.6931 48.4322) ; H5* + #( 32.8647 9.6624 48.2489) ; H5** + #( 31.0429 8.6773 47.9401) ; C4* + #( 30.0440 8.8473 47.5383) ; H4* + #( 31.6749 7.6351 47.2119) ; O4* + #( 31.9159 6.5022 48.0616) ; C1* + #( 31.0691 5.8243 47.9544) ; H1* + #( 31.9300 7.0685 49.4493) ; C2* + #( 32.9024 7.5288 49.6245) ; H2** + #( 31.5672 6.1750 50.4632) ; O2* + #( 31.8416 5.2663 50.3200) ; H2* + #( 30.8618 8.1514 49.3749) ; C3* + #( 31.1122 8.9396 50.0850) ; H3* + #( 29.5351 7.6245 49.5409) ; O3* + #( 33.1890 5.8629 47.7343) ; N1 + #( 34.4004 4.2636 46.4828) ; N3 + #( 33.2062 4.8497 46.7851) ; C2 + #( 35.5600 4.6374 47.0822) ; C4 + #( 35.5444 5.6751 48.0577) ; C5 + #( 34.3565 6.2450 48.3432) ; C6 + #( 36.6977 4.0305 46.7598) ; N4 + #( 32.1661 4.5034 46.2348) ; O2 + #( 37.5405 4.3347 47.2259) ; H41 + #( 36.7033 3.2923 46.0706) ; H42 + #( 36.4713 5.9811 48.5428) ; H5 + #( 34.2986 7.0426 49.0839) ; H6 + )) + +(define rCs + (list rC01 rC02 rC03 rC04 rC05 rC06 rC07 rC08 rC09 rC10)) + +(define rG + (make-constant-rG + #( -0.0018 -0.8207 0.5714 ; dgf-base-tfo + 0.2679 -0.5509 -0.7904 + 0.9634 0.1517 0.2209 + 0.0073 8.4030 0.6232) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4550 8.2120 -2.8810) ; C5* + #( 5.4546 8.8508 -1.9978) ; H5* + #( 5.7588 8.6625 -3.8259) ; H5** + #( 6.4970 7.1480 -2.5980) ; C4* + #( 7.4896 7.5919 -2.5214) ; H4* + #( 6.1630 6.4860 -1.3440) ; O4* + #( 6.5400 5.1200 -1.4190) ; C1* + #( 7.2763 4.9681 -0.6297) ; H1* + #( 7.1940 4.8830 -2.7770) ; C2* + #( 6.8667 3.9183 -3.1647) ; H2** + #( 8.5860 5.0910 -2.6140) ; O2* + #( 8.9510 4.7626 -1.7890) ; H2* + #( 6.5720 6.0040 -3.6090) ; C3* + #( 5.5636 5.7066 -3.8966) ; H3* + #( 7.3801 6.3562 -4.7350) ; O3* + #( 4.7150 0.4910 -0.1360) ; N1 + #( 6.3490 2.1730 -0.6020) ; N3 + #( 5.9530 0.9650 -0.2670) ; C2 + #( 5.2900 2.9790 -0.8260) ; C4 + #( 3.9720 2.6390 -0.7330) ; C5 + #( 3.6770 1.3160 -0.3660) ; C6 + #( 6.8426 0.0056 -0.0019) ; N2 + #( 3.1660 3.7290 -1.0360) ; N7 + #( 5.3170 4.2990 -1.1930) ; N9 + #( 4.0100 4.6780 -1.2990) ; C8 + #( 2.4280 0.8450 -0.2360) ; O6 + #( 4.6151 -0.4677 0.1305) ; H1 + #( 6.6463 -0.9463 0.2729) ; H21 + #( 7.8170 0.2642 -0.0640) ; H22 + #( 3.4421 5.5744 -1.5482) ; H8 + )) + +(define rG01 + (make-constant-rG + #( -0.0043 -0.8175 0.5759 ; dgf-base-tfo + 0.2617 -0.5567 -0.7884 + 0.9651 0.1473 0.2164 + 0.0359 8.3929 0.5532) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4352 8.2183 -2.7757) ; C5* + #( 5.3830 8.7883 -1.8481) ; H5* + #( 5.7729 8.7436 -3.6691) ; H5** + #( 6.4830 7.1518 -2.5252) ; C4* + #( 7.4749 7.5972 -2.4482) ; H4* + #( 6.1626 6.4620 -1.2827) ; O4* + #( 6.5431 5.0992 -1.3905) ; C1* + #( 7.2871 4.9328 -0.6114) ; H1* + #( 7.1852 4.8935 -2.7592) ; C2* + #( 6.8573 3.9363 -3.1645) ; H2** + #( 8.5780 5.1025 -2.6046) ; O2* + #( 8.9516 4.7577 -1.7902) ; H2* + #( 6.5522 6.0300 -3.5612) ; C3* + #( 5.5420 5.7356 -3.8459) ; H3* + #( 7.3487 6.4089 -4.6867) ; O3* + #( 4.7442 0.4514 -0.1390) ; N1 + #( 6.3687 2.1459 -0.5926) ; N3 + #( 5.9795 0.9335 -0.2657) ; C2 + #( 5.3052 2.9471 -0.8125) ; C4 + #( 3.9891 2.5987 -0.7230) ; C5 + #( 3.7016 1.2717 -0.3647) ; C6 + #( 6.8745 -0.0224 -0.0058) ; N2 + #( 3.1770 3.6859 -1.0198) ; N7 + #( 5.3247 4.2695 -1.1710) ; N9 + #( 4.0156 4.6415 -1.2759) ; C8 + #( 2.4553 0.7925 -0.2390) ; O6 + #( 4.6497 -0.5095 0.1212) ; H1 + #( 6.6836 -0.9771 0.2627) ; H21 + #( 7.8474 0.2424 -0.0653) ; H22 + #( 3.4426 5.5361 -1.5199) ; H8 + )) + +(define rG02 + (make-constant-rG + #( 0.5566 0.0449 0.8296 ; dgf-base-tfo + 0.5125 0.7673 -0.3854 + -0.6538 0.6397 0.4041 + -9.1161 -3.7679 -2.9968) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.5778 6.6594 -4.0364) ; C5* + #( 4.9220 7.1963 -4.9204) ; H5* + #( 3.7996 5.9091 -4.1764) ; H5** + #( 5.7873 5.8869 -3.5482) ; C4* + #( 6.0405 5.0875 -4.2446) ; H4* + #( 6.9135 6.8036 -3.4310) ; O4* + #( 7.7293 6.4084 -2.3392) ; C1* + #( 8.7078 6.1815 -2.7624) ; H1* + #( 7.1305 5.1418 -1.7347) ; C2* + #( 7.2040 5.1982 -0.6486) ; H2** + #( 7.7417 4.0392 -2.3813) ; O2* + #( 8.6785 4.1443 -2.5630) ; H2* + #( 5.6666 5.2728 -2.1536) ; C3* + #( 5.1747 5.9805 -1.4863) ; H3* + #( 4.9997 4.0086 -2.1973) ; O3* + #( 10.3245 8.5459 1.5467) ; N1 + #( 9.8051 6.9432 -0.1497) ; N3 + #( 10.5175 7.4328 0.8408) ; C2 + #( 8.7523 7.7422 -0.4228) ; C4 + #( 8.4257 8.9060 0.2099) ; C5 + #( 9.2665 9.3242 1.2540) ; C6 + #( 11.6077 6.7966 1.2752) ; N2 + #( 7.2750 9.4537 -0.3428) ; N7 + #( 7.7962 7.5519 -1.3859) ; N9 + #( 6.9479 8.6157 -1.2771) ; C8 + #( 9.0664 10.4462 1.9610) ; O6 + #( 10.9838 8.7524 2.2697) ; H1 + #( 12.2274 7.0896 2.0170) ; H21 + #( 11.8502 5.9398 0.7984) ; H22 + #( 6.0430 8.9853 -1.7594) ; H8 + )) + +(define rG03 + (make-constant-rG + #( -0.5021 0.0731 0.8617 ; dgf-base-tfo + -0.8112 0.3054 -0.4986 + -0.2996 -0.9494 -0.0940 + 6.4273 -5.1944 -3.7807) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.1214 6.7116 -1.9049) ; C5* + #( 3.3465 5.9610 -2.0607) ; H5* + #( 4.0789 7.2928 -0.9837) ; H5** + #( 5.4170 5.9293 -1.8186) ; C4* + #( 5.4506 5.3400 -0.9023) ; H4* + #( 5.5067 5.0417 -2.9703) ; O4* + #( 6.8650 4.9152 -3.3612) ; C1* + #( 7.1090 3.8577 -3.2603) ; H1* + #( 7.7152 5.7282 -2.3894) ; C2* + #( 8.5029 6.2356 -2.9463) ; H2** + #( 8.1036 4.8568 -1.3419) ; O2* + #( 8.3270 3.9651 -1.6184) ; H2* + #( 6.7003 6.7565 -1.8911) ; C3* + #( 6.5898 7.5329 -2.6482) ; H3* + #( 7.0505 7.2878 -0.6105) ; O3* + #( 9.6740 4.7656 -7.6614) ; N1 + #( 9.0739 4.3013 -5.3941) ; N3 + #( 9.8416 4.2192 -6.4581) ; C2 + #( 7.9885 5.0632 -5.6446) ; C4 + #( 7.6822 5.6856 -6.8194) ; C5 + #( 8.5831 5.5215 -7.8840) ; C6 + #( 10.9733 3.5117 -6.4286) ; N2 + #( 6.4857 6.3816 -6.7035) ; N7 + #( 6.9740 5.3703 -4.7760) ; N9 + #( 6.1133 6.1613 -5.4808) ; C8 + #( 8.4084 6.0747 -9.0933) ; O6 + #( 10.3759 4.5855 -8.3504) ; H1 + #( 11.6254 3.3761 -7.1879) ; H21 + #( 11.1917 3.0460 -5.5593) ; H22 + #( 5.1705 6.6830 -5.3167) ; H8 + )) + +(define rG04 + (make-constant-rG + #( -0.5426 -0.8175 0.1929 ; dgf-base-tfo + 0.8304 -0.5567 -0.0237 + 0.1267 0.1473 0.9809 + -0.5075 8.3929 0.2229) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 5.4352 8.2183 -2.7757) ; C5* + #( 5.3830 8.7883 -1.8481) ; H5* + #( 5.7729 8.7436 -3.6691) ; H5** + #( 6.4830 7.1518 -2.5252) ; C4* + #( 7.4749 7.5972 -2.4482) ; H4* + #( 6.1626 6.4620 -1.2827) ; O4* + #( 6.5431 5.0992 -1.3905) ; C1* + #( 7.2871 4.9328 -0.6114) ; H1* + #( 7.1852 4.8935 -2.7592) ; C2* + #( 6.8573 3.9363 -3.1645) ; H2** + #( 8.5780 5.1025 -2.6046) ; O2* + #( 8.9516 4.7577 -1.7902) ; H2* + #( 6.5522 6.0300 -3.5612) ; C3* + #( 5.5420 5.7356 -3.8459) ; H3* + #( 7.3487 6.4089 -4.6867) ; O3* + #( 3.6343 2.6680 2.0783) ; N1 + #( 5.4505 3.9805 1.2446) ; N3 + #( 4.7540 3.3816 2.1851) ; C2 + #( 4.8805 3.7951 0.0354) ; C4 + #( 3.7416 3.0925 -0.2305) ; C5 + #( 3.0873 2.4980 0.8606) ; C6 + #( 5.1433 3.4373 3.4609) ; N2 + #( 3.4605 3.1184 -1.5906) ; N7 + #( 5.3247 4.2695 -1.1710) ; N9 + #( 4.4244 3.8244 -2.0953) ; C8 + #( 1.9600 1.7805 0.7462) ; O6 + #( 3.2489 2.2879 2.9191) ; H1 + #( 4.6785 3.0243 4.2568) ; H21 + #( 5.9823 3.9654 3.6539) ; H22 + #( 4.2675 3.8876 -3.1721) ; H8 + )) + +(define rG05 + (make-constant-rG + #( -0.5891 0.0449 0.8068 ; dgf-base-tfo + 0.5375 0.7673 0.3498 + -0.6034 0.6397 -0.4762 + -0.3019 -3.7679 -9.5913) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.5778 6.6594 -4.0364) ; C5* + #( 4.9220 7.1963 -4.9204) ; H5* + #( 3.7996 5.9091 -4.1764) ; H5** + #( 5.7873 5.8869 -3.5482) ; C4* + #( 6.0405 5.0875 -4.2446) ; H4* + #( 6.9135 6.8036 -3.4310) ; O4* + #( 7.7293 6.4084 -2.3392) ; C1* + #( 8.7078 6.1815 -2.7624) ; H1* + #( 7.1305 5.1418 -1.7347) ; C2* + #( 7.2040 5.1982 -0.6486) ; H2** + #( 7.7417 4.0392 -2.3813) ; O2* + #( 8.6785 4.1443 -2.5630) ; H2* + #( 5.6666 5.2728 -2.1536) ; C3* + #( 5.1747 5.9805 -1.4863) ; H3* + #( 4.9997 4.0086 -2.1973) ; O3* + #( 10.2594 10.6774 -1.0056) ; N1 + #( 9.7528 8.7080 -2.2631) ; N3 + #( 10.4471 9.7876 -1.9791) ; C2 + #( 8.7271 8.5575 -1.3991) ; C4 + #( 8.4100 9.3803 -0.3580) ; C5 + #( 9.2294 10.5030 -0.1574) ; C6 + #( 11.5110 10.1256 -2.7114) ; N2 + #( 7.2891 8.9068 0.3121) ; N7 + #( 7.7962 7.5519 -1.3859) ; N9 + #( 6.9702 7.8292 -0.3353) ; C8 + #( 9.0349 11.3951 0.8250) ; O6 + #( 10.9013 11.4422 -0.9512) ; H1 + #( 12.1031 10.9341 -2.5861) ; H21 + #( 11.7369 9.5180 -3.4859) ; H22 + #( 6.0888 7.3990 0.1403) ; H8 + )) + +(define rG06 + (make-constant-rG + #( -0.9815 0.0731 -0.1772 ; dgf-base-tfo + 0.1912 0.3054 -0.9328 + -0.0141 -0.9494 -0.3137 + 5.7506 -5.1944 4.7470) + #( -0.8143 -0.5091 -0.2788 ; P-O3*-275-tfo + -0.0433 -0.4257 0.9038 + -0.5788 0.7480 0.3246 + 1.5227 6.9114 -7.0765) + #( 0.3822 -0.7477 0.5430 ; P-O3*-180-tfo + 0.4552 0.6637 0.5935 + -0.8042 0.0203 0.5941 + -6.9472 -4.1186 -5.9108) + #( 0.5640 0.8007 -0.2022 ; P-O3*-60-tfo + -0.8247 0.5587 -0.0878 + 0.0426 0.2162 0.9754 + 6.2694 -7.0540 3.3316) + #( 2.8930 8.5380 -3.3280) ; P + #( 1.6980 7.6960 -3.5570) ; O1P + #( 3.2260 9.5010 -4.4020) ; O2P + #( 4.1590 7.6040 -3.0340) ; O5* + #( 4.1214 6.7116 -1.9049) ; C5* + #( 3.3465 5.9610 -2.0607) ; H5* + #( 4.0789 7.2928 -0.9837) ; H5** + #( 5.4170 5.9293 -1.8186) ; C4* + #( 5.4506 5.3400 -0.9023) ; H4* + #( 5.5067 5.0417 -2.9703) ; O4* + #( 6.8650 4.9152 -3.3612) ; C1* + #( 7.1090 3.8577 -3.2603) ; H1* + #( 7.7152 5.7282 -2.3894) ; C2* + #( 8.5029 6.2356 -2.9463) ; H2** + #( 8.1036 4.8568 -1.3419) ; O2* + #( 8.3270 3.9651 -1.6184) ; H2* + #( 6.7003 6.7565 -1.8911) ; C3* + #( 6.5898 7.5329 -2.6482) ; H3* + #( 7.0505 7.2878 -0.6105) ; O3* + #( 6.6624 3.5061 -8.2986) ; N1 + #( 6.5810 3.2570 -5.9221) ; N3 + #( 6.5151 2.8263 -7.1625) ; C2 + #( 6.8364 4.5817 -5.8882) ; C4 + #( 7.0116 5.4064 -6.9609) ; C5 + #( 6.9173 4.8260 -8.2361) ; C6 + #( 6.2717 1.5402 -7.4250) ; N2 + #( 7.2573 6.7070 -6.5394) ; N7 + #( 6.9740 5.3703 -4.7760) ; N9 + #( 7.2238 6.6275 -5.2453) ; C8 + #( 7.0668 5.5163 -9.3763) ; O6 + #( 6.5754 2.9964 -9.1545) ; H1 + #( 6.1908 1.1105 -8.3354) ; H21 + #( 6.1346 0.9352 -6.6280) ; H22 + #( 7.4108 7.6227 -4.8418) ; H8 + )) + +(define rG07 + (make-constant-rG + #( 0.0894 -0.6059 0.7905 ; dgf-base-tfo + -0.6810 0.5420 0.4924 + -0.7268 -0.5824 -0.3642 + 34.1424 45.9610 -11.8600) + #( -0.8644 -0.4956 -0.0851 ; P-O3*-275-tfo + -0.0427 0.2409 -0.9696 + 0.5010 -0.8345 -0.2294 + 4.0167 54.5377 12.4779) + #( 0.3706 -0.6167 0.6945 ; P-O3*-180-tfo + -0.2867 -0.7872 -0.5460 + 0.8834 0.0032 -0.4686 + -52.9020 18.6313 -0.6709) + #( 0.4155 0.9025 -0.1137 ; P-O3*-60-tfo + 0.9040 -0.4236 -0.0582 + -0.1007 -0.0786 -0.9918 + -7.6624 -25.2080 49.5181) + #( 31.3810 0.1400 47.5810) ; P + #( 29.9860 0.6630 47.6290) ; O1P + #( 31.7210 -0.6460 48.8090) ; O2P + #( 32.4940 1.2540 47.2740) ; O5* + #( 33.8709 0.7918 47.2113) ; C5* + #( 34.1386 0.5870 46.1747) ; H5* + #( 34.0186 -0.0095 47.9353) ; H5** + #( 34.7297 1.9687 47.6685) ; C4* + #( 35.7723 1.6845 47.8113) ; H4* + #( 34.6455 2.9768 46.6660) ; O4* + #( 34.1690 4.1829 47.2627) ; C1* + #( 35.0437 4.7633 47.5560) ; H1* + #( 33.4145 3.7532 48.4954) ; C2* + #( 32.4340 3.3797 48.2001) ; H2** + #( 33.3209 4.6953 49.5217) ; O2* + #( 33.2374 5.6059 49.2295) ; H2* + #( 34.2724 2.5970 48.9773) ; C3* + #( 33.6373 1.8935 49.5157) ; H3* + #( 35.3453 3.1884 49.7285) ; O3* + #( 34.0511 7.8930 43.7791) ; N1 + #( 34.9937 6.3369 45.3199) ; N3 + #( 35.0882 7.3126 44.4200) ; C2 + #( 33.7190 5.9650 45.5374) ; C4 + #( 32.5845 6.4770 44.9458) ; C5 + #( 32.7430 7.5179 43.9914) ; C6 + #( 36.3030 7.7827 44.1036) ; N2 + #( 31.4499 5.8335 45.4368) ; N7 + #( 33.2760 4.9817 46.4043) ; N9 + #( 31.9235 4.9639 46.2934) ; C8 + #( 31.8602 8.1000 43.3695) ; O6 + #( 34.2623 8.6223 43.1283) ; H1 + #( 36.5188 8.5081 43.4347) ; H21 + #( 37.0888 7.3524 44.5699) ; H22 + #( 31.0815 4.4201 46.7218) ; H8 + )) + +(define rG08 + (make-constant-rG + #( 0.2224 0.6335 0.7411 ; dgf-base-tfo + -0.3644 -0.6510 0.6659 + 0.9043 -0.4181 0.0861 + -47.6824 -0.5823 -31.7554) + #( -0.8644 -0.4956 -0.0851 ; P-O3*-275-tfo + -0.0427 0.2409 -0.9696 + 0.5010 -0.8345 -0.2294 + 4.0167 54.5377 12.4779) + #( 0.3706 -0.6167 0.6945 ; P-O3*-180-tfo + -0.2867 -0.7872 -0.5460 + 0.8834 0.0032 -0.4686 + -52.9020 18.6313 -0.6709) + #( 0.4155 0.9025 -0.1137 ; P-O3*-60-tfo + 0.9040 -0.4236 -0.0582 + -0.1007 -0.0786 -0.9918 + -7.6624 -25.2080 49.5181) + #( 31.3810 0.1400 47.5810) ; P + #( 29.9860 0.6630 47.6290) ; O1P + #( 31.7210 -0.6460 48.8090) ; O2P + #( 32.4940 1.2540 47.2740) ; O5* + #( 32.5924 2.3488 48.2255) ; C5* + #( 33.3674 2.1246 48.9584) ; H5* + #( 31.5994 2.5917 48.6037) ; H5** + #( 33.0722 3.5577 47.4258) ; C4* + #( 33.0310 4.4778 48.0089) ; H4* + #( 34.4173 3.3055 47.0316) ; O4* + #( 34.5056 3.3910 45.6094) ; C1* + #( 34.7881 4.4152 45.3663) ; H1* + #( 33.1122 3.1198 45.1010) ; C2* + #( 32.9230 2.0469 45.1369) ; H2** + #( 32.7946 3.6590 43.8529) ; O2* + #( 33.5170 3.6707 43.2207) ; H2* + #( 32.2730 3.8173 46.1566) ; C3* + #( 31.3094 3.3123 46.2244) ; H3* + #( 32.2391 5.2039 45.7807) ; O3* + #( 39.3337 2.7157 44.1441) ; N1 + #( 37.4430 3.8242 45.0824) ; N3 + #( 38.7276 3.7646 44.7403) ; C2 + #( 36.7791 2.6963 44.7704) ; C4 + #( 37.2860 1.5653 44.1678) ; C5 + #( 38.6647 1.5552 43.8235) ; C6 + #( 39.5123 4.8216 44.9936) ; N2 + #( 36.2829 0.6110 44.0078) ; N7 + #( 35.4394 2.4314 44.9931) ; N9 + #( 35.2180 1.1815 44.5128) ; C8 + #( 39.2907 0.6514 43.2796) ; O6 + #( 40.3076 2.8048 43.9352) ; H1 + #( 40.4994 4.9066 44.7977) ; H21 + #( 39.0738 5.6108 45.4464) ; H22 + #( 34.3856 0.4842 44.4185) ; H8 + )) + +(define rG09 + (make-constant-rG + #( -0.9699 -0.1688 -0.1753 ; dgf-base-tfo + -0.1050 -0.3598 0.9271 + -0.2196 0.9176 0.3312 + 45.6217 -38.9484 -12.3208) + #( -0.8644 -0.4956 -0.0851 ; P-O3*-275-tfo + -0.0427 0.2409 -0.9696 + 0.5010 -0.8345 -0.2294 + 4.0167 54.5377 12.4779) + #( 0.3706 -0.6167 0.6945 ; P-O3*-180-tfo + -0.2867 -0.7872 -0.5460 + 0.8834 0.0032 -0.4686 + -52.9020 18.6313 -0.6709) + #( 0.4155 0.9025 -0.1137 ; P-O3*-60-tfo + 0.9040 -0.4236 -0.0582 + -0.1007 -0.0786 -0.9918 + -7.6624 -25.2080 49.5181) + #( 31.3810 0.1400 47.5810) ; P + #( 29.9860 0.6630 47.6290) ; O1P + #( 31.7210 -0.6460 48.8090) ; O2P + #( 32.4940 1.2540 47.2740) ; O5* + #( 33.8709 0.7918 47.2113) ; C5* + #( 34.1386 0.5870 46.1747) ; H5* + #( 34.0186 -0.0095 47.9353) ; H5** + #( 34.7297 1.9687 47.6685) ; C4* + #( 34.5880 2.8482 47.0404) ; H4* + #( 34.3575 2.2770 49.0081) ; O4* + #( 35.5157 2.1993 49.8389) ; C1* + #( 35.9424 3.2010 49.8893) ; H1* + #( 36.4701 1.2820 49.1169) ; C2* + #( 36.1545 0.2498 49.2683) ; H2** + #( 37.8262 1.4547 49.4008) ; O2* + #( 38.0227 1.6945 50.3094) ; H2* + #( 36.2242 1.6797 47.6725) ; C3* + #( 36.4297 0.8197 47.0351) ; H3* + #( 37.0289 2.8480 47.4426) ; O3* + #( 34.3005 3.5042 54.6070) ; N1 + #( 34.7693 3.7936 52.2874) ; N3 + #( 34.4484 4.2541 53.4939) ; C2 + #( 34.9354 2.4584 52.2785) ; C4 + #( 34.8092 1.5915 53.3422) ; C5 + #( 34.4646 2.1367 54.6085) ; C6 + #( 34.2514 5.5708 53.6503) ; N2 + #( 35.0641 0.2835 52.9337) ; N7 + #( 35.2669 1.6690 51.1915) ; N9 + #( 35.3288 0.3954 51.6563) ; C8 + #( 34.3151 1.5317 55.6650) ; O6 + #( 34.0623 3.9797 55.4539) ; H1 + #( 33.9950 6.0502 54.5016) ; H21 + #( 34.3512 6.1432 52.8242) ; H22 + #( 35.5414 -0.6006 51.2679) ; H8 + )) + +(define rG10 + (make-constant-rG + #( -0.0980 -0.9723 0.2122 ; dgf-base-tfo + -0.9731 0.1383 0.1841 + -0.2083 -0.1885 -0.9597 + 17.8469 38.8265 37.0475) + #( -0.8644 -0.4956 -0.0851 ; P-O3*-275-tfo + -0.0427 0.2409 -0.9696 + 0.5010 -0.8345 -0.2294 + 4.0167 54.5377 12.4779) + #( 0.3706 -0.6167 0.6945 ; P-O3*-180-tfo + -0.2867 -0.7872 -0.5460 + 0.8834 0.0032 -0.4686 + -52.9020 18.6313 -0.6709) + #( 0.4155 0.9025 -0.1137 ; P-O3*-60-tfo + 0.9040 -0.4236 -0.0582 + -0.1007 -0.0786 -0.9918 + -7.6624 -25.2080 49.5181) + #( 31.3810 0.1400 47.5810) ; P + #( 29.9860 0.6630 47.6290) ; O1P + #( 31.7210 -0.6460 48.8090) ; O2P + #( 32.4940 1.2540 47.2740) ; O5* + #( 32.5924 2.3488 48.2255) ; C5* + #( 33.3674 2.1246 48.9584) ; H5* + #( 31.5994 2.5917 48.6037) ; H5** + #( 33.0722 3.5577 47.4258) ; C4* + #( 34.0333 3.3761 46.9447) ; H4* + #( 32.0890 3.8338 46.4332) ; O4* + #( 31.6377 5.1787 46.5914) ; C1* + #( 32.2499 5.8016 45.9392) ; H1* + #( 31.9167 5.5319 48.0305) ; C2* + #( 31.1507 5.0820 48.6621) ; H2** + #( 32.0865 6.8890 48.3114) ; O2* + #( 31.5363 7.4819 47.7942) ; H2* + #( 33.2398 4.8224 48.2563) ; C3* + #( 33.3166 4.5570 49.3108) ; H3* + #( 34.2528 5.7056 47.7476) ; O3* + #( 28.2782 6.3049 42.9364) ; N1 + #( 30.4001 5.8547 43.9258) ; N3 + #( 29.6195 6.1568 42.8913) ; C2 + #( 29.7005 5.7006 45.0649) ; C4 + #( 28.3383 5.8221 45.2343) ; C5 + #( 27.5519 6.1461 44.0958) ; C6 + #( 30.1838 6.3385 41.6890) ; N2 + #( 27.9936 5.5926 46.5651) ; N7 + #( 30.2046 5.3825 46.3136) ; N9 + #( 29.1371 5.3398 47.1506) ; C8 + #( 26.3361 6.3024 44.0495) ; O6 + #( 27.8122 6.5394 42.0833) ; H1 + #( 29.7125 6.5595 40.8235) ; H21 + #( 31.1859 6.2231 41.6389) ; H22 + #( 28.9406 5.1504 48.2059) ; H8 + )) + +(define rGs + (list rG01 rG02 rG03 rG04 rG05 rG06 rG07 rG08 rG09 rG10)) + +(define rU + (make-constant-rU + #( -0.0359 -0.8071 0.5894 ; dgf-base-tfo + -0.2669 0.5761 0.7726 + -0.9631 -0.1296 -0.2361 + 0.1584 8.3434 0.5434) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2430 -8.2420 2.8260) ; C5* + #( 5.1974 -8.8497 1.9223) ; H5* + #( 5.5548 -8.7348 3.7469) ; H5** + #( 6.3140 -7.2060 2.5510) ; C4* + #( 7.2954 -7.6762 2.4898) ; H4* + #( 6.0140 -6.5420 1.2890) ; O4* + #( 6.4190 -5.1840 1.3620) ; C1* + #( 7.1608 -5.0495 0.5747) ; H1* + #( 7.0760 -4.9560 2.7270) ; C2* + #( 6.7770 -3.9803 3.1099) ; H2** + #( 8.4500 -5.1930 2.5810) ; O2* + #( 8.8309 -4.8755 1.7590) ; H2* + #( 6.4060 -6.0590 3.5580) ; C3* + #( 5.4021 -5.7313 3.8281) ; H3* + #( 7.1570 -6.4240 4.7070) ; O3* + #( 5.2170 -4.3260 1.1690) ; N1 + #( 4.2960 -2.2560 0.6290) ; N3 + #( 5.4330 -3.0200 0.7990) ; C2 + #( 2.9930 -2.6780 0.7940) ; C4 + #( 2.8670 -4.0630 1.1830) ; C5 + #( 3.9570 -4.8300 1.3550) ; C6 + #( 6.5470 -2.5560 0.6290) ; O2 + #( 2.0540 -1.9000 0.6130) ; O4 + #( 4.4300 -1.3020 0.3600) ; H3 + #( 1.9590 -4.4570 1.3250) ; H5 + #( 3.8460 -5.7860 1.6240) ; H6 + )) + +(define rU01 + (make-constant-rU + #( -0.0137 -0.8012 0.5983 ; dgf-base-tfo + -0.2523 0.5817 0.7733 + -0.9675 -0.1404 -0.2101 + 0.2031 8.3874 0.4228) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2416 -8.2422 2.8181) ; C5* + #( 5.2050 -8.8128 1.8901) ; H5* + #( 5.5368 -8.7738 3.7227) ; H5** + #( 6.3232 -7.2037 2.6002) ; C4* + #( 7.3048 -7.6757 2.5577) ; H4* + #( 6.0635 -6.5092 1.3456) ; O4* + #( 6.4697 -5.1547 1.4629) ; C1* + #( 7.2354 -5.0043 0.7018) ; H1* + #( 7.0856 -4.9610 2.8521) ; C2* + #( 6.7777 -3.9935 3.2487) ; H2** + #( 8.4627 -5.1992 2.7423) ; O2* + #( 8.8693 -4.8638 1.9399) ; H2* + #( 6.3877 -6.0809 3.6362) ; C3* + #( 5.3770 -5.7562 3.8834) ; H3* + #( 7.1024 -6.4754 4.7985) ; O3* + #( 5.2764 -4.2883 1.2538) ; N1 + #( 4.3777 -2.2062 0.7229) ; N3 + #( 5.5069 -2.9779 0.9088) ; C2 + #( 3.0693 -2.6246 0.8500) ; C4 + #( 2.9279 -4.0146 1.2149) ; C5 + #( 4.0101 -4.7892 1.4017) ; C6 + #( 6.6267 -2.5166 0.7728) ; O2 + #( 2.1383 -1.8396 0.6581) ; O4 + #( 4.5223 -1.2489 0.4716) ; H3 + #( 2.0151 -4.4065 1.3290) ; H5 + #( 3.8886 -5.7486 1.6535) ; H6 + )) + +(define rU02 + (make-constant-rU + #( 0.5141 0.0246 0.8574 ; dgf-base-tfo + -0.5547 -0.7529 0.3542 + 0.6542 -0.6577 -0.3734 + -9.1111 -3.4598 -3.2939) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 4.3825 -6.6585 4.0489) ; C5* + #( 4.6841 -7.2019 4.9443) ; H5* + #( 3.6189 -5.8889 4.1625) ; H5** + #( 5.6255 -5.9175 3.5998) ; C4* + #( 5.8732 -5.1228 4.3034) ; H4* + #( 6.7337 -6.8605 3.5222) ; O4* + #( 7.5932 -6.4923 2.4548) ; C1* + #( 8.5661 -6.2983 2.9064) ; H1* + #( 7.0527 -5.2012 1.8322) ; C2* + #( 7.1627 -5.2525 0.7490) ; H2** + #( 7.6666 -4.1249 2.4880) ; O2* + #( 8.5944 -4.2543 2.6981) ; H2* + #( 5.5661 -5.3029 2.2009) ; C3* + #( 5.0841 -6.0018 1.5172) ; H3* + #( 4.9062 -4.0452 2.2042) ; O3* + #( 7.6298 -7.6136 1.4752) ; N1 + #( 8.6945 -8.7046 -0.2857) ; N3 + #( 8.6943 -7.6514 0.6066) ; C2 + #( 7.7426 -9.6987 -0.3801) ; C4 + #( 6.6642 -9.5742 0.5722) ; C5 + #( 6.6391 -8.5592 1.4526) ; C6 + #( 9.5840 -6.8186 0.6136) ; O2 + #( 7.8505 -10.5925 -1.2223) ; O4 + #( 9.4601 -8.7514 -0.9277) ; H3 + #( 5.9281 -10.2509 0.5782) ; H5 + #( 5.8831 -8.4931 2.1028) ; H6 + )) + +(define rU03 + (make-constant-rU + #( -0.4993 0.0476 0.8651 ; dgf-base-tfo + 0.8078 -0.3353 0.4847 + 0.3132 0.9409 0.1290 + 6.2989 -5.2303 -3.8577) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 3.9938 -6.7042 1.9023) ; C5* + #( 3.2332 -5.9343 2.0319) ; H5* + #( 3.9666 -7.2863 0.9812) ; H5** + #( 5.3098 -5.9546 1.8564) ; C4* + #( 5.3863 -5.3702 0.9395) ; H4* + #( 5.3851 -5.0642 3.0076) ; O4* + #( 6.7315 -4.9724 3.4462) ; C1* + #( 7.0033 -3.9202 3.3619) ; H1* + #( 7.5997 -5.8018 2.4948) ; C2* + #( 8.3627 -6.3254 3.0707) ; H2** + #( 8.0410 -4.9501 1.4724) ; O2* + #( 8.2781 -4.0644 1.7570) ; H2* + #( 6.5701 -6.8129 1.9714) ; C3* + #( 6.4186 -7.5809 2.7299) ; H3* + #( 6.9357 -7.3841 0.7235) ; O3* + #( 6.8024 -5.4718 4.8475) ; N1 + #( 7.9218 -5.5700 6.8877) ; N3 + #( 7.8908 -5.0886 5.5944) ; C2 + #( 6.9789 -6.3827 7.4823) ; C4 + #( 5.8742 -6.7319 6.6202) ; C5 + #( 5.8182 -6.2769 5.3570) ; C6 + #( 8.7747 -4.3728 5.1568) ; O2 + #( 7.1154 -6.7509 8.6509) ; O4 + #( 8.7055 -5.3037 7.4491) ; H3 + #( 5.1416 -7.3178 6.9665) ; H5 + #( 5.0441 -6.5310 4.7784) ; H6 + )) + +(define rU04 + (make-constant-rU + #( -0.5669 -0.8012 0.1918 ; dgf-base-tfo + -0.8129 0.5817 0.0273 + -0.1334 -0.1404 -0.9811 + -0.3279 8.3874 0.3355) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2416 -8.2422 2.8181) ; C5* + #( 5.2050 -8.8128 1.8901) ; H5* + #( 5.5368 -8.7738 3.7227) ; H5** + #( 6.3232 -7.2037 2.6002) ; C4* + #( 7.3048 -7.6757 2.5577) ; H4* + #( 6.0635 -6.5092 1.3456) ; O4* + #( 6.4697 -5.1547 1.4629) ; C1* + #( 7.2354 -5.0043 0.7018) ; H1* + #( 7.0856 -4.9610 2.8521) ; C2* + #( 6.7777 -3.9935 3.2487) ; H2** + #( 8.4627 -5.1992 2.7423) ; O2* + #( 8.8693 -4.8638 1.9399) ; H2* + #( 6.3877 -6.0809 3.6362) ; C3* + #( 5.3770 -5.7562 3.8834) ; H3* + #( 7.1024 -6.4754 4.7985) ; O3* + #( 5.2764 -4.2883 1.2538) ; N1 + #( 3.8961 -3.0896 -0.1893) ; N3 + #( 5.0095 -3.8907 -0.0346) ; C2 + #( 3.0480 -2.6632 0.8116) ; C4 + #( 3.4093 -3.1310 2.1292) ; C5 + #( 4.4878 -3.9124 2.3088) ; C6 + #( 5.7005 -4.2164 -0.9842) ; O2 + #( 2.0800 -1.9458 0.5503) ; O4 + #( 3.6834 -2.7882 -1.1190) ; H3 + #( 2.8508 -2.8721 2.9172) ; H5 + #( 4.7188 -4.2247 3.2295) ; H6 + )) + +(define rU05 + (make-constant-rU + #( -0.6298 0.0246 0.7763 ; dgf-base-tfo + -0.5226 -0.7529 -0.4001 + 0.5746 -0.6577 0.4870 + -0.0208 -3.4598 -9.6882) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 4.3825 -6.6585 4.0489) ; C5* + #( 4.6841 -7.2019 4.9443) ; H5* + #( 3.6189 -5.8889 4.1625) ; H5** + #( 5.6255 -5.9175 3.5998) ; C4* + #( 5.8732 -5.1228 4.3034) ; H4* + #( 6.7337 -6.8605 3.5222) ; O4* + #( 7.5932 -6.4923 2.4548) ; C1* + #( 8.5661 -6.2983 2.9064) ; H1* + #( 7.0527 -5.2012 1.8322) ; C2* + #( 7.1627 -5.2525 0.7490) ; H2** + #( 7.6666 -4.1249 2.4880) ; O2* + #( 8.5944 -4.2543 2.6981) ; H2* + #( 5.5661 -5.3029 2.2009) ; C3* + #( 5.0841 -6.0018 1.5172) ; H3* + #( 4.9062 -4.0452 2.2042) ; O3* + #( 7.6298 -7.6136 1.4752) ; N1 + #( 8.5977 -9.5977 0.7329) ; N3 + #( 8.5951 -8.5745 1.6594) ; C2 + #( 7.7372 -9.7371 -0.3364) ; C4 + #( 6.7596 -8.6801 -0.4476) ; C5 + #( 6.7338 -7.6721 0.4408) ; C6 + #( 9.3993 -8.5377 2.5743) ; O2 + #( 7.8374 -10.6990 -1.1008) ; O4 + #( 9.2924 -10.3081 0.8477) ; H3 + #( 6.0932 -8.6982 -1.1929) ; H5 + #( 6.0481 -6.9515 0.3446) ; H6 + )) + +(define rU06 + (make-constant-rU + #( -0.9837 0.0476 -0.1733 ; dgf-base-tfo + -0.1792 -0.3353 0.9249 + -0.0141 0.9409 0.3384 + 5.7793 -5.2303 4.5997) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 3.9938 -6.7042 1.9023) ; C5* + #( 3.2332 -5.9343 2.0319) ; H5* + #( 3.9666 -7.2863 0.9812) ; H5** + #( 5.3098 -5.9546 1.8564) ; C4* + #( 5.3863 -5.3702 0.9395) ; H4* + #( 5.3851 -5.0642 3.0076) ; O4* + #( 6.7315 -4.9724 3.4462) ; C1* + #( 7.0033 -3.9202 3.3619) ; H1* + #( 7.5997 -5.8018 2.4948) ; C2* + #( 8.3627 -6.3254 3.0707) ; H2** + #( 8.0410 -4.9501 1.4724) ; O2* + #( 8.2781 -4.0644 1.7570) ; H2* + #( 6.5701 -6.8129 1.9714) ; C3* + #( 6.4186 -7.5809 2.7299) ; H3* + #( 6.9357 -7.3841 0.7235) ; O3* + #( 6.8024 -5.4718 4.8475) ; N1 + #( 6.6920 -5.0495 7.1354) ; N3 + #( 6.6201 -4.5500 5.8506) ; C2 + #( 6.9254 -6.3614 7.4926) ; C4 + #( 7.1046 -7.2543 6.3718) ; C5 + #( 7.0391 -6.7951 5.1106) ; C6 + #( 6.4083 -3.3696 5.6340) ; O2 + #( 6.9679 -6.6901 8.6800) ; O4 + #( 6.5626 -4.3957 7.8812) ; H3 + #( 7.2781 -8.2254 6.5350) ; H5 + #( 7.1657 -7.4312 4.3503) ; H6 + )) + +(define rU07 + (make-constant-rU + #( -0.9434 0.3172 0.0971 ; dgf-base-tfo + 0.2294 0.4125 0.8816 + 0.2396 0.8539 -0.4619 + 8.3625 -52.7147 1.3745) + #( 0.2765 -0.1121 -0.9545 ; P-O3*-275-tfo + -0.8297 0.4733 -0.2959 + 0.4850 0.8737 0.0379 + -14.7774 -45.2464 21.9088) + #( 0.1063 -0.6334 -0.7665 ; P-O3*-180-tfo + -0.5932 -0.6591 0.4624 + -0.7980 0.4055 -0.4458 + 43.7634 4.3296 28.4890) + #( 0.7136 -0.5032 -0.4873 ; P-O3*-60-tfo + 0.6803 0.3317 0.6536 + -0.1673 -0.7979 0.5791 + -17.1858 41.4390 -27.0751) + #( 21.3880 15.0780 45.5770) ; P + #( 21.9980 14.5500 46.8210) ; O1P + #( 21.1450 14.0270 44.5420) ; O2P + #( 22.1250 16.3600 44.9460) ; O5* + #( 21.5037 16.8594 43.7323) ; C5* + #( 20.8147 17.6663 43.9823) ; H5* + #( 21.1086 16.0230 43.1557) ; H5** + #( 22.5654 17.4874 42.8616) ; C4* + #( 22.1584 17.7243 41.8785) ; H4* + #( 23.0557 18.6826 43.4751) ; O4* + #( 24.4788 18.6151 43.6455) ; C1* + #( 24.9355 19.0840 42.7739) ; H1* + #( 24.7958 17.1427 43.6474) ; C2* + #( 24.5652 16.7400 44.6336) ; H2** + #( 26.1041 16.8773 43.2455) ; O2* + #( 26.7516 17.5328 43.5149) ; H2* + #( 23.8109 16.5979 42.6377) ; C3* + #( 23.5756 15.5686 42.9084) ; H3* + #( 24.2890 16.7447 41.2729) ; O3* + #( 24.9420 19.2174 44.8923) ; N1 + #( 25.2655 20.5636 44.8883) ; N3 + #( 25.1663 21.2219 43.8561) ; C2 + #( 25.6911 21.1219 46.0494) ; C4 + #( 25.8051 20.4068 47.2048) ; C5 + #( 26.2093 20.9962 48.2534) ; C6 + #( 25.4692 19.0221 47.2053) ; O2 + #( 25.0502 18.4827 46.0370) ; O4 + #( 25.9599 22.1772 46.0966) ; H3 + #( 25.5545 18.4409 48.1234) ; H5 + #( 24.7854 17.4265 45.9883) ; H6 + )) + +(define rU08 + (make-constant-rU + #( -0.0080 -0.7928 0.6094 ; dgf-base-tfo + -0.7512 0.4071 0.5197 + -0.6601 -0.4536 -0.5988 + 44.1482 30.7036 2.1088) + #( 0.2765 -0.1121 -0.9545 ; P-O3*-275-tfo + -0.8297 0.4733 -0.2959 + 0.4850 0.8737 0.0379 + -14.7774 -45.2464 21.9088) + #( 0.1063 -0.6334 -0.7665 ; P-O3*-180-tfo + -0.5932 -0.6591 0.4624 + -0.7980 0.4055 -0.4458 + 43.7634 4.3296 28.4890) + #( 0.7136 -0.5032 -0.4873 ; P-O3*-60-tfo + 0.6803 0.3317 0.6536 + -0.1673 -0.7979 0.5791 + -17.1858 41.4390 -27.0751) + #( 21.3880 15.0780 45.5770) ; P + #( 21.9980 14.5500 46.8210) ; O1P + #( 21.1450 14.0270 44.5420) ; O2P + #( 22.1250 16.3600 44.9460) ; O5* + #( 23.5096 16.1227 44.5783) ; C5* + #( 23.5649 15.8588 43.5222) ; H5* + #( 23.9621 15.4341 45.2919) ; H5** + #( 24.2805 17.4138 44.7151) ; C4* + #( 25.3492 17.2309 44.6030) ; H4* + #( 23.8497 18.3471 43.7208) ; O4* + #( 23.4090 19.5681 44.3321) ; C1* + #( 24.2595 20.2496 44.3524) ; H1* + #( 23.0418 19.1813 45.7407) ; C2* + #( 22.0532 18.7224 45.7273) ; H2** + #( 23.1307 20.2521 46.6291) ; O2* + #( 22.8888 21.1051 46.2611) ; H2* + #( 24.0799 18.1326 46.0700) ; C3* + #( 23.6490 17.4370 46.7900) ; H3* + #( 25.3329 18.7227 46.5109) ; O3* + #( 22.2515 20.1624 43.6698) ; N1 + #( 22.4760 21.0609 42.6406) ; N3 + #( 23.6229 21.3462 42.3061) ; C2 + #( 21.3986 21.6081 42.0236) ; C4 + #( 20.1189 21.3012 42.3804) ; C5 + #( 19.1599 21.8516 41.7578) ; C6 + #( 19.8919 20.3745 43.4387) ; O2 + #( 20.9790 19.8423 44.0440) ; O4 + #( 21.5235 22.3222 41.2097) ; H3 + #( 18.8732 20.1200 43.7312) ; H5 + #( 20.8545 19.1313 44.8608) ; H6 + )) + +(define rU09 + (make-constant-rU + #( -0.0317 0.1374 0.9900 ; dgf-base-tfo + -0.3422 -0.9321 0.1184 + 0.9391 -0.3351 0.0765 + -32.1929 25.8198 -28.5088) + #( 0.2765 -0.1121 -0.9545 ; P-O3*-275-tfo + -0.8297 0.4733 -0.2959 + 0.4850 0.8737 0.0379 + -14.7774 -45.2464 21.9088) + #( 0.1063 -0.6334 -0.7665 ; P-O3*-180-tfo + -0.5932 -0.6591 0.4624 + -0.7980 0.4055 -0.4458 + 43.7634 4.3296 28.4890) + #( 0.7136 -0.5032 -0.4873 ; P-O3*-60-tfo + 0.6803 0.3317 0.6536 + -0.1673 -0.7979 0.5791 + -17.1858 41.4390 -27.0751) + #( 21.3880 15.0780 45.5770) ; P + #( 21.9980 14.5500 46.8210) ; O1P + #( 21.1450 14.0270 44.5420) ; O2P + #( 22.1250 16.3600 44.9460) ; O5* + #( 21.5037 16.8594 43.7323) ; C5* + #( 20.8147 17.6663 43.9823) ; H5* + #( 21.1086 16.0230 43.1557) ; H5** + #( 22.5654 17.4874 42.8616) ; C4* + #( 23.0565 18.3036 43.3915) ; H4* + #( 23.5375 16.5054 42.4925) ; O4* + #( 23.6574 16.4257 41.0649) ; C1* + #( 24.4701 17.0882 40.7671) ; H1* + #( 22.3525 16.9643 40.5396) ; C2* + #( 21.5993 16.1799 40.6133) ; H2** + #( 22.4693 17.4849 39.2515) ; O2* + #( 23.0899 17.0235 38.6827) ; H2* + #( 22.0341 18.0633 41.5279) ; C3* + #( 20.9509 18.1709 41.5846) ; H3* + #( 22.7249 19.3020 41.2100) ; O3* + #( 23.8580 15.0648 40.5757) ; N1 + #( 25.1556 14.5982 40.4523) ; N3 + #( 26.1047 15.3210 40.7448) ; C2 + #( 25.3391 13.3315 40.0020) ; C4 + #( 24.2974 12.5148 39.6749) ; C5 + #( 24.5450 11.3410 39.2610) ; C6 + #( 22.9633 12.9979 39.8053) ; O2 + #( 22.8009 14.2648 40.2524) ; O4 + #( 26.3414 12.9194 39.8855) ; H3 + #( 22.1227 12.3533 39.5486) ; H5 + #( 21.7989 14.6788 40.3650) ; H6 + )) + +(define rU10 + (make-constant-rU + #( -0.9674 0.1021 -0.2318 ; dgf-base-tfo + -0.2514 -0.2766 0.9275 + 0.0306 0.9555 0.2933 + 27.8571 -42.1305 -24.4563) + #( 0.2765 -0.1121 -0.9545 ; P-O3*-275-tfo + -0.8297 0.4733 -0.2959 + 0.4850 0.8737 0.0379 + -14.7774 -45.2464 21.9088) + #( 0.1063 -0.6334 -0.7665 ; P-O3*-180-tfo + -0.5932 -0.6591 0.4624 + -0.7980 0.4055 -0.4458 + 43.7634 4.3296 28.4890) + #( 0.7136 -0.5032 -0.4873 ; P-O3*-60-tfo + 0.6803 0.3317 0.6536 + -0.1673 -0.7979 0.5791 + -17.1858 41.4390 -27.0751) + #( 21.3880 15.0780 45.5770) ; P + #( 21.9980 14.5500 46.8210) ; O1P + #( 21.1450 14.0270 44.5420) ; O2P + #( 22.1250 16.3600 44.9460) ; O5* + #( 23.5096 16.1227 44.5783) ; C5* + #( 23.5649 15.8588 43.5222) ; H5* + #( 23.9621 15.4341 45.2919) ; H5** + #( 24.2805 17.4138 44.7151) ; C4* + #( 23.8509 18.1819 44.0720) ; H4* + #( 24.2506 17.8583 46.0741) ; O4* + #( 25.5830 18.0320 46.5775) ; C1* + #( 25.8569 19.0761 46.4256) ; H1* + #( 26.4410 17.1555 45.7033) ; C2* + #( 26.3459 16.1253 46.0462) ; H2** + #( 27.7649 17.5888 45.6478) ; O2* + #( 28.1004 17.9719 46.4616) ; H2* + #( 25.7796 17.2997 44.3513) ; C3* + #( 25.9478 16.3824 43.7871) ; H3* + #( 26.2154 18.4984 43.6541) ; O3* + #( 25.7321 17.6281 47.9726) ; N1 + #( 25.5136 18.5779 48.9560) ; N3 + #( 25.2079 19.7276 48.6503) ; C2 + #( 25.6482 18.1987 50.2518) ; C4 + #( 25.9847 16.9266 50.6092) ; C5 + #( 26.0918 16.6439 51.8416) ; C6 + #( 26.2067 15.9515 49.5943) ; O2 + #( 26.0713 16.3497 48.3080) ; O4 + #( 25.4890 18.9105 51.0618) ; H3 + #( 26.4742 14.9310 49.8682) ; H5 + #( 26.2346 15.6394 47.4975) ; H6 + )) + +(define rUs + (list rU01 rU02 rU03 rU04 rU05 rU06 rU07 rU08 rU09 rU10)) + +(define rG* + (make-constant-rG + #( -0.2067 -0.0264 0.9780 ; dgf-base-tfo + 0.9770 -0.0586 0.2049 + 0.0519 0.9979 0.0379 + 1.0331 -46.8078 -36.4742) + #( -0.8644 -0.4956 -0.0851 ; P-O3*-275-tfo + -0.0427 0.2409 -0.9696 + 0.5010 -0.8345 -0.2294 + 4.0167 54.5377 12.4779) + #( 0.3706 -0.6167 0.6945 ; P-O3*-180-tfo + -0.2867 -0.7872 -0.5460 + 0.8834 0.0032 -0.4686 + -52.9020 18.6313 -0.6709) + #( 0.4155 0.9025 -0.1137 ; P-O3*-60-tfo + 0.9040 -0.4236 -0.0582 + -0.1007 -0.0786 -0.9918 + -7.6624 -25.2080 49.5181) + #( 31.3810 0.1400 47.5810) ; P + #( 29.9860 0.6630 47.6290) ; O1P + #( 31.7210 -0.6460 48.8090) ; O2P + #( 32.4940 1.2540 47.2740) ; O5* + #( 32.1610 2.2370 46.2560) ; C5* + #( 31.2986 2.8190 46.5812) ; H5* + #( 32.0980 1.7468 45.2845) ; H5** + #( 33.3476 3.1959 46.1947) ; C4* + #( 33.2668 3.8958 45.3630) ; H4* + #( 33.3799 3.9183 47.4216) ; O4* + #( 34.6515 3.7222 48.0398) ; C1* + #( 35.2947 4.5412 47.7180) ; H1* + #( 35.1756 2.4228 47.4827) ; C2* + #( 34.6778 1.5937 47.9856) ; H2** + #( 36.5631 2.2672 47.4798) ; O2* + #( 37.0163 2.6579 48.2305) ; H2* + #( 34.6953 2.5043 46.0448) ; C3* + #( 34.5444 1.4917 45.6706) ; H3* + #( 35.6679 3.3009 45.3487) ; O3* + #( 37.4804 4.0914 52.2559) ; N1 + #( 36.9670 4.1312 49.9281) ; N3 + #( 37.8045 4.2519 50.9550) ; C2 + #( 35.7171 3.8264 50.3222) ; C4 + #( 35.2668 3.6420 51.6115) ; C5 + #( 36.2037 3.7829 52.6706) ; C6 + #( 39.0869 4.5552 50.7092) ; N2 + #( 33.9075 3.3338 51.6102) ; N7 + #( 34.6126 3.6358 49.5108) ; N9 + #( 33.5805 3.3442 50.3425) ; C8 + #( 35.9958 3.6512 53.8724) ; O6 + #( 38.2106 4.2053 52.9295) ; H1 + #( 39.8218 4.6863 51.3896) ; H21 + #( 39.3420 4.6857 49.7407) ; H22 + #( 32.5194 3.1070 50.2664) ; H8 + )) + +(define rU* + (make-constant-rU + #( -0.0109 0.5907 0.8068 ; dgf-base-tfo + 0.2217 -0.7853 0.5780 + 0.9751 0.1852 -0.1224 + -1.4225 -11.0956 -2.5217) + #( -0.8313 -0.4738 -0.2906 ; P-O3*-275-tfo + 0.0649 0.4366 -0.8973 + 0.5521 -0.7648 -0.3322 + 1.6833 6.8060 -7.0011) + #( 0.3445 -0.7630 0.5470 ; P-O3*-180-tfo + -0.4628 -0.6450 -0.6082 + 0.8168 -0.0436 -0.5753 + -6.8179 -3.9778 -5.9887) + #( 0.5855 0.7931 -0.1682 ; P-O3*-60-tfo + 0.8103 -0.5790 0.0906 + -0.0255 -0.1894 -0.9816 + 6.1203 -7.1051 3.1984) + #( 2.6760 -8.4960 3.2880) ; P + #( 1.4950 -7.6230 3.4770) ; O1P + #( 2.9490 -9.4640 4.3740) ; O2P + #( 3.9730 -7.5950 3.0340) ; O5* + #( 5.2430 -8.2420 2.8260) ; C5* + #( 5.1974 -8.8497 1.9223) ; H5* + #( 5.5548 -8.7348 3.7469) ; H5** + #( 6.3140 -7.2060 2.5510) ; C4* + #( 5.8744 -6.2116 2.4731) ; H4* + #( 7.2798 -7.2260 3.6420) ; O4* + #( 8.5733 -6.9410 3.1329) ; C1* + #( 8.9047 -6.0374 3.6446) ; H1* + #( 8.4429 -6.6596 1.6327) ; C2* + #( 9.2880 -7.1071 1.1096) ; H2** + #( 8.2502 -5.2799 1.4754) ; O2* + #( 8.7676 -4.7284 2.0667) ; H2* + #( 7.1642 -7.4416 1.3021) ; C3* + #( 7.4125 -8.5002 1.2260) ; H3* + #( 6.5160 -6.9772 0.1267) ; O3* + #( 9.4531 -8.1107 3.4087) ; N1 + #( 11.5931 -9.0015 3.6357) ; N3 + #( 10.8101 -7.8950 3.3748) ; C2 + #( 11.1439 -10.2744 3.9206) ; C4 + #( 9.7056 -10.4026 3.9332) ; C5 + #( 8.9192 -9.3419 3.6833) ; C6 + #( 11.3013 -6.8063 3.1326) ; O2 + #( 11.9431 -11.1876 4.1375) ; O4 + #( 12.5840 -8.8673 3.6158) ; H3 + #( 9.2891 -11.2898 4.1313) ; H5 + #( 7.9263 -9.4537 3.6977) ; H6 + )) + + + +; -- PARTIAL INSTANTIATIONS --------------------------------------------------- + +(def-struct #f var id tfo nuc) + +; Add a single-quote at the start of this line if you want lazy computation +(begin + +(def-macro (mk-var i tfo nuc) + `(make-var ,i ,tfo ,nuc)) + +(def-macro (absolute-pos var p) + `(tfo-apply (var-tfo ,var) ,p)) + +(def-macro (lazy-computation-of expr) + expr) +) + +'; Remove the single-quote from this line if you want lazy computation +(begin + +(def-macro (mk-var i tfo nuc) + `(make-var ,i ,tfo (make-relative-nuc ,tfo ,nuc))) + +(def-macro (absolute-pos var p) + `(force ,p)) + +(def-macro (lazy-computation-of expr) + `(delay ,expr)) +) + +(def-macro (atom-pos atom var) + `(let ((v ,var)) + (absolute-pos v (,atom (var-nuc v))))) + +(define (get-var id lst) + (let ((v (car lst))) + (if (= id (var-id v)) + v + (get-var id (cdr lst))))) + +(define (make-relative-nuc tfo n) + (cond ((rA? n) + (make-rA + (nuc-dgf-base-tfo n) + (nuc-P-O3*-275-tfo n) + (nuc-P-O3*-180-tfo n) + (nuc-P-O3*-60-tfo n) + (lazy-computation-of (tfo-apply tfo (nuc-P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O1P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5** n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2** n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-N1 n))) + (lazy-computation-of (tfo-apply tfo (nuc-N3 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C6 n))) + (lazy-computation-of (tfo-apply tfo (rA-N6 n))) + (lazy-computation-of (tfo-apply tfo (rA-N7 n))) + (lazy-computation-of (tfo-apply tfo (rA-N9 n))) + (lazy-computation-of (tfo-apply tfo (rA-C8 n))) + (lazy-computation-of (tfo-apply tfo (rA-H2 n))) + (lazy-computation-of (tfo-apply tfo (rA-H61 n))) + (lazy-computation-of (tfo-apply tfo (rA-H62 n))) + (lazy-computation-of (tfo-apply tfo (rA-H8 n))))) + ((rC? n) + (make-rC + (nuc-dgf-base-tfo n) + (nuc-P-O3*-275-tfo n) + (nuc-P-O3*-180-tfo n) + (nuc-P-O3*-60-tfo n) + (lazy-computation-of (tfo-apply tfo (nuc-P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O1P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5** n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2** n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-N1 n))) + (lazy-computation-of (tfo-apply tfo (nuc-N3 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C6 n))) + (lazy-computation-of (tfo-apply tfo (rC-N4 n))) + (lazy-computation-of (tfo-apply tfo (rC-O2 n))) + (lazy-computation-of (tfo-apply tfo (rC-H41 n))) + (lazy-computation-of (tfo-apply tfo (rC-H42 n))) + (lazy-computation-of (tfo-apply tfo (rC-H5 n))) + (lazy-computation-of (tfo-apply tfo (rC-H6 n))))) + ((rG? n) + (make-rG + (nuc-dgf-base-tfo n) + (nuc-P-O3*-275-tfo n) + (nuc-P-O3*-180-tfo n) + (nuc-P-O3*-60-tfo n) + (lazy-computation-of (tfo-apply tfo (nuc-P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O1P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5** n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2** n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-N1 n))) + (lazy-computation-of (tfo-apply tfo (nuc-N3 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C6 n))) + (lazy-computation-of (tfo-apply tfo (rG-N2 n))) + (lazy-computation-of (tfo-apply tfo (rG-N7 n))) + (lazy-computation-of (tfo-apply tfo (rG-N9 n))) + (lazy-computation-of (tfo-apply tfo (rG-C8 n))) + (lazy-computation-of (tfo-apply tfo (rG-O6 n))) + (lazy-computation-of (tfo-apply tfo (rG-H1 n))) + (lazy-computation-of (tfo-apply tfo (rG-H21 n))) + (lazy-computation-of (tfo-apply tfo (rG-H22 n))) + (lazy-computation-of (tfo-apply tfo (rG-H8 n))))) + (else + (make-rU + (nuc-dgf-base-tfo n) + (nuc-P-O3*-275-tfo n) + (nuc-P-O3*-180-tfo n) + (nuc-P-O3*-60-tfo n) + (lazy-computation-of (tfo-apply tfo (nuc-P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O1P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2P n))) + (lazy-computation-of (tfo-apply tfo (nuc-O5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H5** n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O4* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H1* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2** n))) + (lazy-computation-of (tfo-apply tfo (nuc-O2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H2* n))) + (lazy-computation-of (tfo-apply tfo (nuc-C3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-H3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-O3* n))) + (lazy-computation-of (tfo-apply tfo (nuc-N1 n))) + (lazy-computation-of (tfo-apply tfo (nuc-N3 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C2 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C4 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C5 n))) + (lazy-computation-of (tfo-apply tfo (nuc-C6 n))) + (lazy-computation-of (tfo-apply tfo (rU-O2 n))) + (lazy-computation-of (tfo-apply tfo (rU-O4 n))) + (lazy-computation-of (tfo-apply tfo (rU-H3 n))) + (lazy-computation-of (tfo-apply tfo (rU-H5 n))) + (lazy-computation-of (tfo-apply tfo (rU-H6 n))))))) + +; -- SEARCH ------------------------------------------------------------------- + +; Sequential backtracking algorithm + +(define (search partial-inst domains constraint?) + (if (null? domains) + (list partial-inst) + (let ((remaining-domains (cdr domains))) + + (define (try-assignments lst) + (if (null? lst) + '() + (let ((var (car lst))) + (if (constraint? var partial-inst) + (let* ((subsols1 + (search + (cons var partial-inst) + remaining-domains + constraint?)) + (subsols2 + (try-assignments (cdr lst)))) + (append subsols1 subsols2)) + (try-assignments (cdr lst)))))) + + (try-assignments ((car domains) partial-inst))))) + +; -- DOMAINS ------------------------------------------------------------------ + +; Primary structure: strand A CUGCCACGUCUG, strand B CAGACGUGGCAG +; +; Secondary structure: strand A CUGCCACGUCUG +; |||||||||||| +; GACGGUGCAGAC strand B +; +; Tertiary structure: +; +; 5' end of strand A C1----G12 3' end of strand B +; U2-------A11 +; G3-------C10 +; C4-----G9 +; C5---G8 +; A6 +; G6-C7 +; C5----G8 +; A4-------U9 +; G3--------C10 +; A2-------U11 +; 5' end of strand B C1----G12 3' end of strand A +; +; "helix", "stacked" and "connected" describe the spatial relationship +; between two consecutive nucleotides. E.g. the nucleotides C1 and U2 +; from the strand A. +; +; "wc" (stands for Watson-Crick and is a type of base-pairing), +; and "wc-dumas" describe the spatial relationship between +; nucleotides from two chains that are growing in opposite directions. +; E.g. the nucleotides C1 from strand A and G12 from strand B. + +; Dynamic Domains + +; Given, +; "ref" a nucleotide which is already positioned, +; "nuc" the nucleotide to be placed, +; and "tfo" a transformation matrix which expresses the desired +; relationship between "ref" and "nuc", +; the function "dgf-base" computes the transformation matrix that +; places the nucleotide "nuc" in the given relationship to "ref". + +(define (dgf-base tfo ref nuc) + (let* ((ref-nuc (var-nuc ref)) + (align + (tfo-inv-ortho + (cond ((rA? ref-nuc) + (tfo-align (atom-pos nuc-C1* ref) + (atom-pos rA-N9 ref) + (atom-pos nuc-C4 ref))) + ((rC? ref-nuc) + (tfo-align (atom-pos nuc-C1* ref) + (atom-pos nuc-N1 ref) + (atom-pos nuc-C2 ref))) + ((rG? ref-nuc) + (tfo-align (atom-pos nuc-C1* ref) + (atom-pos rG-N9 ref) + (atom-pos nuc-C4 ref))) + (else + (tfo-align (atom-pos nuc-C1* ref) + (atom-pos nuc-N1 ref) + (atom-pos nuc-C2 ref))))))) + (tfo-combine (nuc-dgf-base-tfo nuc) + (tfo-combine tfo align)))) + +; Placement of first nucleotide. + +(define (reference nuc i) + (lambda (partial-inst) + (list (mk-var i tfo-id nuc)))) + +; The transformation matrix for wc is from: +; +; Chandrasekaran R. et al (1989) A Re-Examination of the Crystal +; Structure of A-DNA Using Fiber Diffraction Data. J. Biomol. +; Struct. & Dynamics 6(6):1189-1202. + +(define wc-tfo + '#(-1.0000 0.0028 -0.0019 + 0.0028 0.3468 -0.9379 + -0.0019 -0.9379 -0.3468 + -0.0080 6.0730 8.7208)) + +(define (wc nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base wc-tfo ref nuc))) + (list (mk-var i tfo nuc))))) + +(define wc-Dumas-tfo + '#(-0.9737 -0.1834 0.1352 + -0.1779 0.2417 -0.9539 + 0.1422 -0.9529 -0.2679 + 0.4837 6.2649 8.0285)) + +(define (wc-Dumas nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base wc-Dumas-tfo ref nuc))) + (list (mk-var i tfo nuc))))) + +(define helix5*-tfo + '#( 0.9886 -0.0961 0.1156 + 0.1424 0.8452 -0.5152 + -0.0482 0.5258 0.8492 + -3.8737 0.5480 3.8024)) + +(define (helix5* nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base helix5*-tfo ref nuc))) + (list (mk-var i tfo nuc))))) + +(define helix3*-tfo + '#( 0.9886 0.1424 -0.0482 + -0.0961 0.8452 0.5258 + 0.1156 -0.5152 0.8492 + 3.4426 2.0474 -3.7042)) + +(define (helix3* nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base helix3*-tfo ref nuc))) + (list (mk-var i tfo nuc))))) + +(define G37-A38-tfo + '#( 0.9991 0.0164 -0.0387 + -0.0375 0.7616 -0.6470 + 0.0189 0.6478 0.7615 + -3.3018 0.9975 2.5585)) + +(define (G37-A38 nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base G37-A38-tfo ref nuc))) + (mk-var i tfo nuc)))) + +(define (stacked5* nuc i j) + (lambda (partial-inst) + (cons ((G37-A38 nuc i j) partial-inst) + ((helix5* nuc i j) partial-inst)))) + +(define A38-G37-tfo + '#( 0.9991 -0.0375 0.0189 + 0.0164 0.7616 0.6478 + -0.0387 -0.6470 0.7615 + 3.3819 0.7718 -2.5321)) + +(define (A38-G37 nuc i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (tfo (dgf-base A38-G37-tfo ref nuc))) + (mk-var i tfo nuc)))) + +(define (stacked3* nuc i j) + (lambda (partial-inst) + (cons ((A38-G37 nuc i j) partial-inst) + ((helix3* nuc i j) partial-inst)))) + +(define (P-O3* nucs i j) + (lambda (partial-inst) + (let* ((ref (get-var j partial-inst)) + (align + (tfo-inv-ortho + (tfo-align (atom-pos nuc-O3* ref) + (atom-pos nuc-C3* ref) + (atom-pos nuc-C4* ref))))) + (let loop ((lst nucs) (domains '())) + (if (null? lst) + domains + (let ((nuc (car lst))) + (let ((tfo-60 (tfo-combine (nuc-P-O3*-60-tfo nuc) align)) + (tfo-180 (tfo-combine (nuc-P-O3*-180-tfo nuc) align)) + (tfo-275 (tfo-combine (nuc-P-O3*-275-tfo nuc) align))) + (loop (cdr lst) + (cons (mk-var i tfo-60 nuc) + (cons (mk-var i tfo-180 nuc) + (cons (mk-var i tfo-275 nuc) domains))))))))))) + +; -- PROBLEM STATEMENT -------------------------------------------------------- + +; Define anticodon problem -- Science 253:1255 Figure 3a, 3b and 3c + +(define anticodon-domains + (list + (reference rC 27 ) + (helix5* rC 28 27) + (helix5* rA 29 28) + (helix5* rG 30 29) + (helix5* rA 31 30) + (wc rU 39 31) + (helix5* rC 40 39) + (helix5* rU 41 40) + (helix5* rG 42 41) + (helix5* rG 43 42) + (stacked3* rA 38 39) + (stacked3* rG 37 38) + (stacked3* rA 36 37) + (stacked3* rA 35 36) + (stacked3* rG 34 35);<-. Distance + (P-O3* rCs 32 31); | Constraint + (P-O3* rUs 33 32);<-' 3.0 Angstroms + )) + +; Anticodon constraint + +(define (anticodon-constraint? v partial-inst) + (if (= (var-id v) 33) + (let ((p (atom-pos nuc-P (get-var 34 partial-inst))) ; P in nucleotide 34 + (o3* (atom-pos nuc-O3* v))) ; O3' in nucl. 33 + (FLOAT<= (pt-dist p o3*) 3.0)) ; check distance + #t)) + +(define (anticodon) + (search '() anticodon-domains anticodon-constraint?)) + +; Define pseudoknot problem -- Science 253:1255 Figure 4a and 4b + +(define pseudoknot-domains + (list + (reference rA 23 ) + (wc-Dumas rU 8 23) + (helix3* rG 22 23) + (wc-Dumas rC 9 22) + (helix3* rG 21 22) + (wc-Dumas rC 10 21) + (helix3* rC 20 21) + (wc-Dumas rG 11 20) + (helix3* rU* 19 20);<-. + (wc-Dumas rA 12 19); | Distance +; ; | Constraint +; Helix 1 ; | 4.0 Angstroms + (helix3* rC 3 19); | + (wc-Dumas rG 13 3); | + (helix3* rC 2 3); | + (wc-Dumas rG 14 2); | + (helix3* rC 1 2); | + (wc-Dumas rG* 15 1); | +; ; | +; L2 LOOP ; | + (P-O3* rUs 16 15); | + (P-O3* rCs 17 16); | + (P-O3* rAs 18 17);<-' +; +; L1 LOOP + (helix3* rU 7 8);<-. + (P-O3* rCs 4 3); | Constraint + (stacked5* rU 5 4); | 4.5 Angstroms + (stacked5* rC 6 5);<-' + )) + +; Pseudoknot constraint + +(define (pseudoknot-constraint? v partial-inst) + (case (var-id v) + ((18) + (let ((p (atom-pos nuc-P (get-var 19 partial-inst))) + (o3* (atom-pos nuc-O3* v))) + (FLOAT<= (pt-dist p o3*) 4.0))) + ((6) + (let ((p (atom-pos nuc-P (get-var 7 partial-inst))) + (o3* (atom-pos nuc-O3* v))) + (FLOAT<= (pt-dist p o3*) 4.5))) + (else + #t))) + +(define (pseudoknot) + (search '() pseudoknot-domains pseudoknot-constraint?)) + +; -- TESTING ----------------------------------------------------------------- + +(define (list-of-atoms n) + (append (list-of-common-atoms n) + (list-of-specific-atoms n))) + +(define (list-of-common-atoms n) + (list + (nuc-P n) + (nuc-O1P n) + (nuc-O2P n) + (nuc-O5* n) + (nuc-C5* n) + (nuc-H5* n) + (nuc-H5** n) + (nuc-C4* n) + (nuc-H4* n) + (nuc-O4* n) + (nuc-C1* n) + (nuc-H1* n) + (nuc-C2* n) + (nuc-H2** n) + (nuc-O2* n) + (nuc-H2* n) + (nuc-C3* n) + (nuc-H3* n) + (nuc-O3* n) + (nuc-N1 n) + (nuc-N3 n) + (nuc-C2 n) + (nuc-C4 n) + (nuc-C5 n) + (nuc-C6 n))) + +(define (list-of-specific-atoms n) + (cond ((rA? n) + (list + (rA-N6 n) + (rA-N7 n) + (rA-N9 n) + (rA-C8 n) + (rA-H2 n) + (rA-H61 n) + (rA-H62 n) + (rA-H8 n))) + ((rC? n) + (list + (rC-N4 n) + (rC-O2 n) + (rC-H41 n) + (rC-H42 n) + (rC-H5 n) + (rC-H6 n))) + ((rG? n) + (list + (rG-N2 n) + (rG-N7 n) + (rG-N9 n) + (rG-C8 n) + (rG-O6 n) + (rG-H1 n) + (rG-H21 n) + (rG-H22 n) + (rG-H8 n))) + (else + (list + (rU-O2 n) + (rU-O4 n) + (rU-H3 n) + (rU-H5 n) + (rU-H6 n))))) + +(define (var-most-distant-atom v) + + (define (distance pos) + (let ((abs-pos (absolute-pos v pos))) + (let ((x (pt-x abs-pos)) (y (pt-y abs-pos)) (z (pt-z abs-pos))) + (FLOATsqrt (FLOAT+ (FLOAT* x x) (FLOAT* y y) (FLOAT* z z)))))) + + (maximum (map distance (list-of-atoms (var-nuc v))))) + +(define (sol-most-distant-atom s) + (maximum (map var-most-distant-atom s))) + +(define (most-distant-atom sols) + (maximum (map sol-most-distant-atom sols))) + +(define (maximum lst) + (let loop ((m (car lst)) (l (cdr lst))) + (if (null? l) + m + (let ((x (car l))) + (loop (if (FLOAT> x m) x m) (cdr l)))))) + +(define (check) + (length (pseudoknot))) + +(define (run) + (most-distant-atom (pseudoknot))) + +; To run program, evaluate: (run) + +(time (run)) diff --git a/collects/tests/mzscheme/benchmarks/common/nucleic2.ss b/collects/tests/mzscheme/benchmarks/common/nucleic2.ss new file mode 100644 index 0000000000..9e96273041 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/nucleic2.ss @@ -0,0 +1,2 @@ + +(module nucleic2 "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/puzzle.sch b/collects/tests/mzscheme/benchmarks/common/puzzle.sch new file mode 100644 index 0000000000..9120df4e17 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/puzzle.sch @@ -0,0 +1,169 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: puzzle.sch +; Description: PUZZLE benchmark +; Author: Richard Gabriel, after Forrest Baskett +; Created: 12-Apr-85 +; Modified: 12-Apr-85 14:20:23 (Bob Shaw) +; 11-Aug-87 (Will Clinger) +; 22-Jan-88 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define (iota n) + (do ((n n (- n 1)) + (list '() (cons (- n 1) list))) + ((zero? n) list))) + +;;; PUZZLE -- Forest Baskett's Puzzle benchmark, originally written in Pascal. + +(define size 1048575) +(define classmax 3) +(define typemax 12) + +(define *iii* 0) +(define *kount* 0) +(define *d* 8) + +(define *piececount* (make-vector (+ classmax 1) 0)) +(define *class* (make-vector (+ typemax 1) 0)) +(define *piecemax* (make-vector (+ typemax 1) 0)) +(define *puzzle* (make-vector (+ size 1))) +(define *p* (make-vector (+ typemax 1))) +(for-each (lambda (i) (vector-set! *p* i (make-vector (+ size 1)))) + (iota (+ typemax 1))) + +(define (fit i j) + (let ((end (vector-ref *piecemax* i))) + (do ((k 0 (+ k 1))) + ((or (> k end) + (and (vector-ref (vector-ref *p* i) k) + (vector-ref *puzzle* (+ j k)))) + (if (> k end) #t #f))))) + +(define (place i j) + (let ((end (vector-ref *piecemax* i))) + (do ((k 0 (+ k 1))) + ((> k end)) + (cond ((vector-ref (vector-ref *p* i) k) + (vector-set! *puzzle* (+ j k) #t) + #t))) + (vector-set! *piececount* + (vector-ref *class* i) + (- (vector-ref *piececount* (vector-ref *class* i)) 1)) + (do ((k j (+ k 1))) + ((or (> k size) (not (vector-ref *puzzle* k))) + ; (newline) + ; (display "*Puzzle* filled") + (if (> k size) 0 k))))) + +(define (puzzle-remove i j) + (let ((end (vector-ref *piecemax* i))) + (do ((k 0 (+ k 1))) + ((> k end)) + (cond ((vector-ref (vector-ref *p* i) k) + (vector-set! *puzzle* (+ j k) #f) + #f))) + (vector-set! *piececount* + (vector-ref *class* i) + (+ (vector-ref *piececount* (vector-ref *class* i)) 1)))) + + +(define (trial j) + (let ((k 0)) + (call-with-current-continuation + (lambda (return) + (do ((i 0 (+ i 1))) + ((> i typemax) (set! *kount* (+ *kount* 1)) '()) + (cond + ((not + (zero? + (vector-ref *piececount* (vector-ref *class* i)))) + (cond + ((fit i j) + (set! k (place i j)) + (cond + ((or (trial k) (zero? k)) + ;(trial-output (+ i 1) (+ k 1)) + (set! *kount* (+ *kount* 1)) + (return #t)) + (else (puzzle-remove i j)))))))))))) + +(define (trial-output x y) + (newline) + (display (string-append "Piece " + (number->string x '(int)) + " at " + (number->string y '(int)) + "."))) + +(define (definePiece iclass ii jj kk) + (let ((index 0)) + (do ((i 0 (+ i 1))) + ((> i ii)) + (do ((j 0 (+ j 1))) + ((> j jj)) + (do ((k 0 (+ k 1))) + ((> k kk)) + (set! index (+ i (* *d* (+ j (* *d* k))))) + (vector-set! (vector-ref *p* *iii*) index #t)))) + (vector-set! *class* *iii* iclass) + (vector-set! *piecemax* *iii* index) + (cond ((not (= *iii* typemax)) + (set! *iii* (+ *iii* 1)))))) + +(define (start) + (do ((m 0 (+ m 1))) + ((> m size)) + (vector-set! *puzzle* m #t)) + (do ((i 1 (+ i 1))) + ((> i 5)) + (do ((j 1 (+ j 1))) + ((> j 5)) + (do ((k 1 (+ k 1))) + ((> k 5)) + (vector-set! *puzzle* (+ i (* *d* (+ j (* *d* k)))) #f)))) + (do ((i 0 (+ i 1))) + ((> i typemax)) + (do ((m 0 (+ m 1))) + ((> m size)) + (vector-set! (vector-ref *p* i) m #f))) + (set! *iii* 0) + (definePiece 0 3 1 0) + (definePiece 0 1 0 3) + (definePiece 0 0 3 1) + (definePiece 0 1 3 0) + (definePiece 0 3 0 1) + (definePiece 0 0 1 3) + + (definePiece 1 2 0 0) + (definePiece 1 0 2 0) + (definePiece 1 0 0 2) + + (definePiece 2 1 1 0) + (definePiece 2 1 0 1) + (definePiece 2 0 1 1) + + (definePiece 3 1 1 1) + + (vector-set! *piececount* 0 13) + (vector-set! *piececount* 1 3) + (vector-set! *piececount* 2 1) + (vector-set! *piececount* 3 1) + (let ((m (+ (* *d* (+ *d* 1)) 1)) + (n 0)) + (cond ((fit 0 m) (set! n (place 0 m))) + (else (begin (newline) (display "Error.")))) + (cond ((trial n) + (begin (newline) + (display "Success in ") + (write *kount*) + (display " trials.") + (newline))) + (else (begin (newline) (display "Failure.")))))) + +;;; call: (start) + +(time (start)) + + diff --git a/collects/tests/mzscheme/benchmarks/common/puzzle.ss b/collects/tests/mzscheme/benchmarks/common/puzzle.ss new file mode 100644 index 0000000000..c661a89e47 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/puzzle.ss @@ -0,0 +1,2 @@ + +(module puzzle "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/sboyer.sch b/collects/tests/mzscheme/benchmarks/common/sboyer.sch new file mode 100644 index 0000000000..37befe9d87 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/sboyer.sch @@ -0,0 +1,774 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: sboyer.sch +; Description: The Boyer benchmark +; Author: Bob Boyer +; Created: 5-Apr-85 +; Modified: 10-Apr-85 14:52:20 (Bob Shaw) +; 22-Jul-87 (Will Clinger) +; 2-Jul-88 (Will Clinger -- distinguished #f and the empty list) +; 13-Feb-97 (Will Clinger -- fixed bugs in unifier and rules, +; rewrote to eliminate property lists, and added +; a scaling parameter suggested by Bob Boyer) +; 19-Mar-99 (Will Clinger -- cleaned up comments) +; 4-Apr-01 (Will Clinger -- changed four 1- symbols to sub1) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; SBOYER -- Logic programming benchmark, originally written by Bob Boyer. +;;; Much less CONS-intensive than NBOYER because it uses Henry Baker's +;;; "sharing cons". + +; Note: The version of this benchmark that appears in Dick Gabriel's book +; contained several bugs that are corrected here. These bugs are discussed +; by Henry Baker, "The Boyer Benchmark Meets Linear Logic", ACM SIGPLAN Lisp +; Pointers 6(4), October-December 1993, pages 3-10. The fixed bugs are: +; +; The benchmark now returns a boolean result. +; FALSEP and TRUEP use TERM-MEMBER? rather than MEMV (which is called MEMBER +; in Common Lisp) +; ONE-WAY-UNIFY1 now treats numbers correctly +; ONE-WAY-UNIFY1-LST now treats empty lists correctly +; Rule 19 has been corrected (this rule was not touched by the original +; benchmark, but is used by this version) +; Rules 84 and 101 have been corrected (but these rules are never touched +; by the benchmark) +; +; According to Baker, these bug fixes make the benchmark 10-25% slower. +; Please do not compare the timings from this benchmark against those of +; the original benchmark. +; +; This version of the benchmark also prints the number of rewrites as a sanity +; check, because it is too easy for a buggy version to return the correct +; boolean result. The correct number of rewrites is +; +; n rewrites peak live storage (approximate, in bytes) +; 0 95024 +; 1 591777 +; 2 1813975 +; 3 5375678 +; 4 16445406 +; 5 51507739 + +; Sboyer is a 2-phase benchmark. +; The first phase attaches lemmas to symbols. This phase is not timed, +; but it accounts for very little of the runtime anyway. +; The second phase creates the test problem, and tests to see +; whether it is implied by the lemmas. + +(define (sboyer-benchmark . args) + (let ((n (if (null? args) 0 (car args)))) + (setup-boyer) + (time (test-boyer n)))) + +(define (setup-boyer) #t) ; assigned below +(define (test-boyer) #t) ; assigned below + +(define (id x) x) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The first phase. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; In the original benchmark, it stored a list of lemmas on the +; property lists of symbols. +; In the new benchmark, it maintains an association list of +; symbols and symbol-records, and stores the list of lemmas +; within the symbol-records. + +(let () + + (define (setup) + (add-lemma-lst + (quote ((equal (compile form) + (reverse (codegen (optimize form) + (nil)))) + (equal (eqp x y) + (equal (fix x) + (fix y))) + (equal (greaterp x y) + (lessp y x)) + (equal (lesseqp x y) + (not (lessp y x))) + (equal (greatereqp x y) + (not (lessp x y))) + (equal (boolean x) + (or (equal x (t)) + (equal x (f)))) + (equal (iff x y) + (and (implies x y) + (implies y x))) + (equal (even1 x) + (if (zerop x) + (t) + (odd (sub1 x)))) + (equal (countps- l pred) + (countps-loop l pred (zero))) + (equal (fact- i) + (fact-loop i 1)) + (equal (reverse- x) + (reverse-loop x (nil))) + (equal (divides x y) + (zerop (remainder y x))) + (equal (assume-true var alist) + (cons (cons var (t)) + alist)) + (equal (assume-false var alist) + (cons (cons var (f)) + alist)) + (equal (tautology-checker x) + (tautologyp (normalize x) + (nil))) + (equal (falsify x) + (falsify1 (normalize x) + (nil))) + (equal (prime x) + (and (not (zerop x)) + (not (equal x (add1 (zero)))) + (prime1 x (sub1 x)))) + (equal (and p q) + (if p (if q (t) + (f)) + (f))) + (equal (or p q) + (if p (t) + (if q (t) + (f)))) + (equal (not p) + (if p (f) + (t))) + (equal (implies p q) + (if p (if q (t) + (f)) + (t))) + (equal (fix x) + (if (numberp x) + x + (zero))) + (equal (if (if a b c) + d e) + (if a (if b d e) + (if c d e))) + (equal (zerop x) + (or (equal x (zero)) + (not (numberp x)))) + (equal (plus (plus x y) + z) + (plus x (plus y z))) + (equal (equal (plus a b) + (zero)) + (and (zerop a) + (zerop b))) + (equal (difference x x) + (zero)) + (equal (equal (plus a b) + (plus a c)) + (equal (fix b) + (fix c))) + (equal (equal (zero) + (difference x y)) + (not (lessp y x))) + (equal (equal x (difference x y)) + (and (numberp x) + (or (equal x (zero)) + (zerop y)))) + (equal (meaning (plus-tree (append x y)) + a) + (plus (meaning (plus-tree x) + a) + (meaning (plus-tree y) + a))) + (equal (meaning (plus-tree (plus-fringe x)) + a) + (fix (meaning x a))) + (equal (append (append x y) + z) + (append x (append y z))) + (equal (reverse (append a b)) + (append (reverse b) + (reverse a))) + (equal (times x (plus y z)) + (plus (times x y) + (times x z))) + (equal (times (times x y) + z) + (times x (times y z))) + (equal (equal (times x y) + (zero)) + (or (zerop x) + (zerop y))) + (equal (exec (append x y) + pds envrn) + (exec y (exec x pds envrn) + envrn)) + (equal (mc-flatten x y) + (append (flatten x) + y)) + (equal (member x (append a b)) + (or (member x a) + (member x b))) + (equal (member x (reverse y)) + (member x y)) + (equal (length (reverse x)) + (length x)) + (equal (member a (intersect b c)) + (and (member a b) + (member a c))) + (equal (nth (zero) + i) + (zero)) + (equal (exp i (plus j k)) + (times (exp i j) + (exp i k))) + (equal (exp i (times j k)) + (exp (exp i j) + k)) + (equal (reverse-loop x y) + (append (reverse x) + y)) + (equal (reverse-loop x (nil)) + (reverse x)) + (equal (count-list z (sort-lp x y)) + (plus (count-list z x) + (count-list z y))) + (equal (equal (append a b) + (append a c)) + (equal b c)) + (equal (plus (remainder x y) + (times y (quotient x y))) + (fix x)) + (equal (power-eval (big-plus1 l i base) + base) + (plus (power-eval l base) + i)) + (equal (power-eval (big-plus x y i base) + base) + (plus i (plus (power-eval x base) + (power-eval y base)))) + (equal (remainder y 1) + (zero)) + (equal (lessp (remainder x y) + y) + (not (zerop y))) + (equal (remainder x x) + (zero)) + (equal (lessp (quotient i j) + i) + (and (not (zerop i)) + (or (zerop j) + (not (equal j 1))))) + (equal (lessp (remainder x y) + x) + (and (not (zerop y)) + (not (zerop x)) + (not (lessp x y)))) + (equal (power-eval (power-rep i base) + base) + (fix i)) + (equal (power-eval (big-plus (power-rep i base) + (power-rep j base) + (zero) + base) + base) + (plus i j)) + (equal (gcd x y) + (gcd y x)) + (equal (nth (append a b) + i) + (append (nth a i) + (nth b (difference i (length a))))) + (equal (difference (plus x y) + x) + (fix y)) + (equal (difference (plus y x) + x) + (fix y)) + (equal (difference (plus x y) + (plus x z)) + (difference y z)) + (equal (times x (difference c w)) + (difference (times c x) + (times w x))) + (equal (remainder (times x z) + z) + (zero)) + (equal (difference (plus b (plus a c)) + a) + (plus b c)) + (equal (difference (add1 (plus y z)) + z) + (add1 y)) + (equal (lessp (plus x y) + (plus x z)) + (lessp y z)) + (equal (lessp (times x z) + (times y z)) + (and (not (zerop z)) + (lessp x y))) + (equal (lessp y (plus x y)) + (not (zerop x))) + (equal (gcd (times x z) + (times y z)) + (times z (gcd x y))) + (equal (value (normalize x) + a) + (value x a)) + (equal (equal (flatten x) + (cons y (nil))) + (and (nlistp x) + (equal x y))) + (equal (listp (gopher x)) + (listp x)) + (equal (samefringe x y) + (equal (flatten x) + (flatten y))) + (equal (equal (greatest-factor x y) + (zero)) + (and (or (zerop y) + (equal y 1)) + (equal x (zero)))) + (equal (equal (greatest-factor x y) + 1) + (equal x 1)) + (equal (numberp (greatest-factor x y)) + (not (and (or (zerop y) + (equal y 1)) + (not (numberp x))))) + (equal (times-list (append x y)) + (times (times-list x) + (times-list y))) + (equal (prime-list (append x y)) + (and (prime-list x) + (prime-list y))) + (equal (equal z (times w z)) + (and (numberp z) + (or (equal z (zero)) + (equal w 1)))) + (equal (greatereqp x y) + (not (lessp x y))) + (equal (equal x (times x y)) + (or (equal x (zero)) + (and (numberp x) + (equal y 1)))) + (equal (remainder (times y x) + y) + (zero)) + (equal (equal (times a b) + 1) + (and (not (equal a (zero))) + (not (equal b (zero))) + (numberp a) + (numberp b) + (equal (sub1 a) + (zero)) + (equal (sub1 b) + (zero)))) + (equal (lessp (length (delete x l)) + (length l)) + (member x l)) + (equal (sort2 (delete x l)) + (delete x (sort2 l))) + (equal (dsort x) + (sort2 x)) + (equal (length (cons x1 + (cons x2 + (cons x3 (cons x4 + (cons x5 + (cons x6 x7))))))) + (plus 6 (length x7))) + (equal (difference (add1 (add1 x)) + 2) + (fix x)) + (equal (quotient (plus x (plus x y)) + 2) + (plus x (quotient y 2))) + (equal (sigma (zero) + i) + (quotient (times i (add1 i)) + 2)) + (equal (plus x (add1 y)) + (if (numberp y) + (add1 (plus x y)) + (add1 x))) + (equal (equal (difference x y) + (difference z y)) + (if (lessp x y) + (not (lessp y z)) + (if (lessp z y) + (not (lessp y x)) + (equal (fix x) + (fix z))))) + (equal (meaning (plus-tree (delete x y)) + a) + (if (member x y) + (difference (meaning (plus-tree y) + a) + (meaning x a)) + (meaning (plus-tree y) + a))) + (equal (times x (add1 y)) + (if (numberp y) + (plus x (times x y)) + (fix x))) + (equal (nth (nil) + i) + (if (zerop i) + (nil) + (zero))) + (equal (last (append a b)) + (if (listp b) + (last b) + (if (listp a) + (cons (car (last a)) + b) + b))) + (equal (equal (lessp x y) + z) + (if (lessp x y) + (equal (t) z) + (equal (f) z))) + (equal (assignment x (append a b)) + (if (assignedp x a) + (assignment x a) + (assignment x b))) + (equal (car (gopher x)) + (if (listp x) + (car (flatten x)) + (zero))) + (equal (flatten (cdr (gopher x))) + (if (listp x) + (cdr (flatten x)) + (cons (zero) + (nil)))) + (equal (quotient (times y x) + y) + (if (zerop y) + (zero) + (fix x))) + (equal (get j (set i val mem)) + (if (eqp j i) + val + (get j mem))))))) + + (define (add-lemma-lst lst) + (cond ((null? lst) + #t) + (else (add-lemma (car lst)) + (add-lemma-lst (cdr lst))))) + + (define (add-lemma term) + (cond ((and (pair? term) + (eq? (car term) + (quote equal)) + (pair? (cadr term))) + (put (car (cadr term)) + (quote lemmas) + (cons + (translate-term term) + (get (car (cadr term)) (quote lemmas))))) + (else (error "ADD-LEMMA did not like term: " term)))) + + ; Translates a term by replacing its constructor symbols by symbol-records. + + (define (translate-term term) + (cond ((not (pair? term)) + term) + (else (cons (symbol->symbol-record (car term)) + (translate-args (cdr term)))))) + + (define (translate-args lst) + (cond ((null? lst) + '()) + (else (cons (translate-term (car lst)) + (translate-args (cdr lst)))))) + + ; For debugging only, so the use of MAP does not change + ; the first-order character of the benchmark. + + (define (untranslate-term term) + (cond ((not (pair? term)) + term) + (else (cons (get-name (car term)) + (map untranslate-term (cdr term)))))) + + ; A symbol-record is represented as a vector with two fields: + ; the symbol (for debugging) and + ; the list of lemmas associated with the symbol. + + (define (put sym property value) + (put-lemmas! (symbol->symbol-record sym) value)) + + (define (get sym property) + (get-lemmas (symbol->symbol-record sym))) + + (define (symbol->symbol-record sym) + (let ((x (assq sym *symbol-records-alist*))) + (if x + (cdr x) + (let ((r (make-symbol-record sym))) + (set! *symbol-records-alist* + (cons (cons sym r) + *symbol-records-alist*)) + r)))) + + ; Association list of symbols and symbol-records. + + (define *symbol-records-alist* '()) + + ; A symbol-record is represented as a vector with two fields: + ; the symbol (for debugging) and + ; the list of lemmas associated with the symbol. + + (define (make-symbol-record sym) + (vector sym '())) + + (define (put-lemmas! symbol-record lemmas) + (vector-set! symbol-record 1 lemmas)) + + (define (get-lemmas symbol-record) + (vector-ref symbol-record 1)) + + (define (get-name symbol-record) + (vector-ref symbol-record 0)) + + (define (symbol-record-equal? r1 r2) + (eq? r1 r2)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; + ; The second phase. + ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (define (test n) + (let ((term + (apply-subst + (translate-alist + (quote ((x f (plus (plus a b) + (plus c (zero)))) + (y f (times (times a b) + (plus c d))) + (z f (reverse (append (append a b) + (nil)))) + (u equal (plus a b) + (difference x y)) + (w lessp (remainder a b) + (member a (length b)))))) + (translate-term + (do ((term + (quote (implies (and (implies x y) + (and (implies y z) + (and (implies z u) + (implies u w)))) + (implies x w))) + (list 'or term '(f))) + (n n (- n 1))) + ((zero? n) term)))))) + (tautp term))) + + (define (translate-alist alist) + (cond ((null? alist) + '()) + (else (cons (cons (caar alist) + (translate-term (cdar alist))) + (translate-alist (cdr alist)))))) + + (define (apply-subst alist term) + (cond ((not (pair? term)) + (let ((temp-temp (assq term alist))) + (if temp-temp + (cdr temp-temp) + term))) + (else (cons (car term) + (apply-subst-lst alist (cdr term)))))) + + (define (apply-subst-lst alist lst) + (cond ((null? lst) + '()) + (else (cons (apply-subst alist (car lst)) + (apply-subst-lst alist (cdr lst)))))) + + (define (tautp x) + (tautologyp (rewrite x) + '() '())) + + (define (tautologyp x true-lst false-lst) + (cond ((truep x true-lst) + #t) + ((falsep x false-lst) + #f) + ((not (pair? x)) + #f) + ((eq? (car x) if-constructor) + (cond ((truep (cadr x) + true-lst) + (tautologyp (caddr x) + true-lst false-lst)) + ((falsep (cadr x) + false-lst) + (tautologyp (cadddr x) + true-lst false-lst)) + (else (and (tautologyp (caddr x) + (cons (cadr x) + true-lst) + false-lst) + (tautologyp (cadddr x) + true-lst + (cons (cadr x) + false-lst)))))) + (else #f))) + + (define if-constructor '*) ; becomes (symbol->symbol-record 'if) + + (define rewrite-count 0) ; sanity check + + ; The next procedure is Henry Baker's sharing CONS, which avoids + ; allocation if the result is already in hand. + ; The REWRITE and REWRITE-ARGS procedures have been modified to + ; use SCONS instead of CONS. + + (define (scons x y original) + (if (and (eq? x (car original)) + (eq? y (cdr original))) + original + (cons x y))) + + (define (rewrite term) + (set! rewrite-count (+ rewrite-count 1)) + (cond ((not (pair? term)) + term) + (else (rewrite-with-lemmas (scons (car term) + (rewrite-args (cdr term)) + term) + (get-lemmas (car term)))))) + + (define (rewrite-args lst) + (cond ((null? lst) + '()) + (else (scons (rewrite (car lst)) + (rewrite-args (cdr lst)) + lst)))) + + (define (rewrite-with-lemmas term lst) + (cond ((null? lst) + term) + ((one-way-unify term (cadr (car lst))) + (rewrite ( apply-subst unify-subst (caddr (car lst))))) + (else (rewrite-with-lemmas term (cdr lst))))) + + (define unify-subst '*) + + (define (one-way-unify term1 term2) + (begin (set! unify-subst '()) + (one-way-unify1 term1 term2))) + + (define (one-way-unify1 term1 term2) + (cond ((not (pair? term2)) + (let ((temp-temp (assq term2 unify-subst))) + (cond (temp-temp + (term-equal? term1 (cdr temp-temp))) + ((number? term2) ; This bug fix makes + (equal? term1 term2)) ; nboyer 10-25% slower! + (else + (set! unify-subst (cons (cons term2 term1) + unify-subst)) + #t)))) + ((not (pair? term1)) + #f) + ((eq? (car term1) + (car term2)) + (one-way-unify1-lst (cdr term1) + (cdr term2))) + (else #f))) + + (define (one-way-unify1-lst lst1 lst2) + (cond ((null? lst1) + (null? lst2)) + ((null? lst2) + #f) + ((one-way-unify1 (car lst1) + (car lst2)) + (one-way-unify1-lst (cdr lst1) + (cdr lst2))) + (else #f))) + + (define (falsep x lst) + (or (term-equal? x false-term) + (term-member? x lst))) + + (define (truep x lst) + (or (term-equal? x true-term) + (term-member? x lst))) + + (define false-term '*) ; becomes (translate-term '(f)) + (define true-term '*) ; becomes (translate-term '(t)) + + ; The next two procedures were in the original benchmark + ; but were never used. + + (define (trans-of-implies n) + (translate-term + (list (quote implies) + (trans-of-implies1 n) + (list (quote implies) + 0 n)))) + + (define (trans-of-implies1 n) + (cond ((equal? n 1) + (list (quote implies) + 0 1)) + (else (list (quote and) + (list (quote implies) + (- n 1) + n) + (trans-of-implies1 (- n 1)))))) + + ; Translated terms can be circular structures, which can't be + ; compared using Scheme's equal? and member procedures, so we + ; use these instead. + + (define (term-equal? x y) + (cond ((pair? x) + (and (pair? y) + (symbol-record-equal? (car x) (car y)) + (term-args-equal? (cdr x) (cdr y)))) + (else (equal? x y)))) + + (define (term-args-equal? lst1 lst2) + (cond ((null? lst1) + (null? lst2)) + ((null? lst2) + #f) + ((term-equal? (car lst1) (car lst2)) + (term-args-equal? (cdr lst1) (cdr lst2))) + (else #f))) + + (define (term-member? x lst) + (cond ((null? lst) + #f) + ((term-equal? x (car lst)) + #t) + (else (term-member? x (cdr lst))))) + + (set! setup-boyer + (lambda () + (set! *symbol-records-alist* '()) + (set! if-constructor (symbol->symbol-record 'if)) + (set! false-term (translate-term '(f))) + (set! true-term (translate-term '(t))) + (setup))) + + (set! test-boyer + (lambda (n) + (set! rewrite-count 0) + (let ((answer (test n))) + (write rewrite-count) + (display " rewrites") + (newline) + (if answer + rewrite-count + #f))))) + +(sboyer-benchmark 5) diff --git a/collects/tests/mzscheme/benchmarks/common/sboyer.ss b/collects/tests/mzscheme/benchmarks/common/sboyer.ss new file mode 100644 index 0000000000..d9f73bf479 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/sboyer.ss @@ -0,0 +1,2 @@ + +(module sboyer "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/sort1.sch b/collects/tests/mzscheme/benchmarks/common/sort1.sch new file mode 100644 index 0000000000..b7cea29767 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/sort1.sch @@ -0,0 +1,143 @@ +; This benchmark uses the code for Larceny's standard sort procedure. +; +; Usage: +; (sort-benchmark sorter n) +; +; where +; sorter is a sort procedure (usually sort or sort1) whose calling +; convention is compatible with Larceny's +; n is the number of fixnums to sort + +(define sort1 + (let () + +;;; File : sort.scm +;;; Author : Richard A. O'Keefe (based on Prolog code by D.H.D.Warren) +;;; Updated: 11 June 1991 +; +; $Id: sort.sch 264 1998-12-14 16:44:08Z lth $ +; +; Code originally obtained from Scheme Repository, since hacked. +; +; Sort and Sort! will sort lists and vectors. The former returns a new +; data structure; the latter sorts the data structure in-place. A +; mergesort algorithm is used. + +; Destructive merge of two sorted lists. + +(define (merge!! a b less?) + + (define (loop r a b) + (if (less? (car b) (car a)) + (begin (set-cdr! r b) + (if (null? (cdr b)) + (set-cdr! b a) + (loop b a (cdr b)) )) + ;; (car a) <= (car b) + (begin (set-cdr! r a) + (if (null? (cdr a)) + (set-cdr! a b) + (loop a (cdr a) b)) )) ) + + (cond ((null? a) b) + ((null? b) a) + ((less? (car b) (car a)) + (if (null? (cdr b)) + (set-cdr! b a) + (loop b a (cdr b))) + b) + (else ; (car a) <= (car b) + (if (null? (cdr a)) + (set-cdr! a b) + (loop a (cdr a) b)) + a))) + +; Sort procedure which copies the input list and then sorts the +; new list imperatively. Due to Richard O'Keefe; algorithm +; attributed to D.H.D. Warren + +(define (sort!! seq less?) + + (define (step n) + (cond ((> n 2) + (let* ((j (quotient n 2)) + (a (step j)) + (k (- n j)) + (b (step k))) + (merge!! a b less?))) + ((= n 2) + (let ((x (car seq)) + (y (cadr seq)) + (p seq)) + (set! seq (cddr seq)) + (if (less? y x) + (begin + (set-car! p y) + (set-car! (cdr p) x))) + (set-cdr! (cdr p) '()) + p)) + ((= n 1) + (let ((p seq)) + (set! seq (cdr seq)) + (set-cdr! p '()) + p)) + (else + '()))) + + (step (length seq))) + +(define (sort! seq less?) + (cond ((null? seq) + seq) + ((pair? seq) + (sort!! seq less?)) + ((vector? seq) + (do ((l (sort!! (vector->list seq) less?) (cdr l)) + (i 0 (+ i 1))) + ((null? l) seq) + (vector-set! seq i (car l)))) + (else + (error "sort!: not a valid sequence: " seq)))) + +(define (sort seq less?) + (cond ((null? seq) + seq) + ((pair? seq) + (sort!! (list-copy seq) less?)) + ((vector? seq) + (list->vector (sort!! (vector->list seq) less?))) + (else + (error "sort: not a valid sequence: " seq)))) + +; eof + + ; This is pretty much optimal for Larceny. + + (define (list-copy l) + (define (loop l prev) + (if (null? l) + #t + (let ((q (cons (car l) '()))) + (set-cdr! prev q) + (loop (cdr l) q)))) + (if (null? l) + l + (let ((first (cons (car l) '()))) + (loop (cdr l) first) + first))) + + sort)) + + +(define (rgen n m) + (let loop ((n n) (l '())) + (if (zero? n) + l + (loop (- n 1) (cons (random m) l))))) + +(define (sort-benchmark sorter n) + (let ((l (rgen n 1000000))) + (time (sorter l <)))) + +(sort-benchmark sort1 1000000) + diff --git a/collects/tests/mzscheme/benchmarks/common/sort1.ss b/collects/tests/mzscheme/benchmarks/common/sort1.ss new file mode 100644 index 0000000000..11a05c85e2 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/sort1.ss @@ -0,0 +1,2 @@ + +(module sort1 "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/tak.sch b/collects/tests/mzscheme/benchmarks/common/tak.sch new file mode 100644 index 0000000000..6519c5279e --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/tak.sch @@ -0,0 +1,25 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: tak.sch +; Description: TAK benchmark from the Gabriel tests +; Author: Richard Gabriel +; Created: 12-Apr-85 +; Modified: 12-Apr-85 09:58:18 (Bob Shaw) +; 22-Jul-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; TAK -- A vanilla version of the TAKeuchi function + +(define (tak x y z) + (if (not (< y x)) + z + (tak (tak (- x 1) y z) + (tak (- y 1) z x) + (tak (- z 1) x y)))) + +;;; call: (tak 18 12 6) + +(time (tak 18 12 2)) + + diff --git a/collects/tests/mzscheme/benchmarks/common/tak.ss b/collects/tests/mzscheme/benchmarks/common/tak.ss new file mode 100644 index 0000000000..bc4ec8d0a5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/tak.ss @@ -0,0 +1,2 @@ + +(module tak "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/takl.sch b/collects/tests/mzscheme/benchmarks/common/takl.sch new file mode 100644 index 0000000000..d7f3082abd --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/takl.sch @@ -0,0 +1,41 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: takl.sch +; Description: TAKL benchmark from the Gabriel tests +; Author: Richard Gabriel +; Created: 12-Apr-85 +; Modified: 12-Apr-85 10:07:00 (Bob Shaw) +; 22-Jul-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; TAKL -- The TAKeuchi function using lists as counters. + +(define (listn n) + (if (not (= 0 n)) + (cons n (listn (- n 1))) + '())) + +(define 18l (listn 18)) +(define 12l (listn 12)) +(define 6l (listn 2)) + +(define (mas x y z) + (if (not (shorterp y x)) + z + (mas (mas (cdr x) + y z) + (mas (cdr y) + z x) + (mas (cdr z) + x y)))) + +(define (shorterp x y) + (and (not (null? y)) + (or (null? x) + (shorterp (cdr x) + (cdr y))))) + +;;; call: (mas 18l 12l 6l) + +(time (mas 18l 12l 6l)) diff --git a/collects/tests/mzscheme/benchmarks/common/takl.ss b/collects/tests/mzscheme/benchmarks/common/takl.ss new file mode 100644 index 0000000000..1023cb61ab --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/takl.ss @@ -0,0 +1,2 @@ + +(module takl "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/takr.sch b/collects/tests/mzscheme/benchmarks/common/takr.sch new file mode 100644 index 0000000000..da55b81256 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/takr.sch @@ -0,0 +1,521 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: takr.sch +; Description: TAKR benchmark +; Author: Richard Gabriel +; Created: 12-Apr-85 +; Modified: 12-Apr-85 10:12:43 (Bob Shaw) +; 22-Jul-87 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; TAKR -- 100 function (count `em) version of TAK that tries to defeat cache +;;; memory effects. Results should be the same as for TAK on stack machines. +;;; Distribution of calls is not completely flat. + +(define (tak0 x y z) + (cond ((not (< y x)) z) + (else (tak1 (tak37 (- x 1) y z) + (tak11 (- y 1) z x) + (tak17 (- z 1) x y))))) +(define (tak1 x y z) + (cond ((not (< y x)) z) + (else (tak2 (tak74 (- x 1) y z) + (tak22 (- y 1) z x) + (tak34 (- z 1) x y))))) +(define (tak2 x y z) + (cond ((not (< y x)) z) + (else (tak3 (tak11 (- x 1) y z) + (tak33 (- y 1) z x) + (tak51 (- z 1) x y))))) +(define (tak3 x y z) + (cond ((not (< y x)) z) + (else (tak4 (tak48 (- x 1) y z) + (tak44 (- y 1) z x) + (tak68 (- z 1) x y))))) +(define (tak4 x y z) + (cond ((not (< y x)) z) + (else (tak5 (tak85 (- x 1) y z) + (tak55 (- y 1) z x) + (tak85 (- z 1) x y))))) +(define (tak5 x y z) + (cond ((not (< y x)) z) + (else (tak6 (tak22 (- x 1) y z) + (tak66 (- y 1) z x) + (tak2 (- z 1) x y))))) +(define (tak6 x y z) + (cond ((not (< y x)) z) + (else (tak7 (tak59 (- x 1) y z) + (tak77 (- y 1) z x) + (tak19 (- z 1) x y))))) +(define (tak7 x y z) + (cond ((not (< y x)) z) + (else (tak8 (tak96 (- x 1) y z) + (tak88 (- y 1) z x) + (tak36 (- z 1) x y))))) +(define (tak8 x y z) + (cond ((not (< y x)) z) + (else (tak9 (tak33 (- x 1) y z) + (tak99 (- y 1) z x) + (tak53 (- z 1) x y))))) +(define (tak9 x y z) + (cond ((not (< y x)) z) + (else (tak10 (tak70 (- x 1) y z) + (tak10 (- y 1) z x) + (tak70 (- z 1) x y))))) +(define (tak10 x y z) + (cond ((not (< y x)) z) + (else (tak11 (tak7 (- x 1) y z) + (tak21 (- y 1) z x) + (tak87 (- z 1) x y))))) +(define (tak11 x y z) + (cond ((not (< y x)) z) + (else (tak12 (tak44 (- x 1) y z) + (tak32 (- y 1) z x) + (tak4 (- z 1) x y))))) +(define (tak12 x y z) + (cond ((not (< y x)) z) + (else (tak13 (tak81 (- x 1) y z) + (tak43 (- y 1) z x) + (tak21 (- z 1) x y))))) + +(define (tak13 x y z) + (cond ((not (< y x)) z) + (else (tak14 (tak18 (- x 1) y z) + (tak54 (- y 1) z x) + (tak38 (- z 1) x y))))) +(define (tak14 x y z) + (cond ((not (< y x)) z) + (else (tak15 (tak55 (- x 1) y z) + (tak65 (- y 1) z x) + (tak55 (- z 1) x y))))) +(define (tak15 x y z) + (cond ((not (< y x)) z) + (else (tak16 (tak92 (- x 1) y z) + (tak76 (- y 1) z x) + (tak72 (- z 1) x y))))) +(define (tak16 x y z) + (cond ((not (< y x)) z) + (else (tak17 (tak29 (- x 1) y z) + (tak87 (- y 1) z x) + (tak89 (- z 1) x y))))) +(define (tak17 x y z) + (cond ((not (< y x)) z) + (else (tak18 (tak66 (- x 1) y z) + (tak98 (- y 1) z x) + (tak6 (- z 1) x y))))) +(define (tak18 x y z) + (cond ((not (< y x)) z) + (else (tak19 (tak3 (- x 1) y z) + (tak9 (- y 1) z x) + (tak23 (- z 1) x y))))) +(define (tak19 x y z) + (cond ((not (< y x)) z) + (else (tak20 (tak40 (- x 1) y z) + (tak20 (- y 1) z x) + (tak40 (- z 1) x y))))) +(define (tak20 x y z) + (cond ((not (< y x)) z) + (else (tak21 (tak77 (- x 1) y z) + (tak31 (- y 1) z x) + (tak57 (- z 1) x y))))) +(define (tak21 x y z) + (cond ((not (< y x)) z) + (else (tak22 (tak14 (- x 1) y z) + (tak42 (- y 1) z x) + (tak74 (- z 1) x y))))) +(define (tak22 x y z) + (cond ((not (< y x)) z) + (else (tak23 (tak51 (- x 1) y z) + (tak53 (- y 1) z x) + (tak91 (- z 1) x y))))) +(define (tak23 x y z) + (cond ((not (< y x)) z) + (else (tak24 (tak88 (- x 1) y z) + (tak64 (- y 1) z x) + (tak8 (- z 1) x y))))) +(define (tak24 x y z) + (cond ((not (< y x)) z) + (else (tak25 (tak25 (- x 1) y z) + (tak75 (- y 1) z x) + (tak25 (- z 1) x y))))) +(define (tak25 x y z) + (cond ((not (< y x)) z) + (else (tak26 (tak62 (- x 1) y z) + (tak86 (- y 1) z x) + (tak42 (- z 1) x y))))) +(define (tak26 x y z) + (cond ((not (< y x)) z) + (else (tak27 (tak99 (- x 1) y z) + (tak97 (- y 1) z x) + (tak59 (- z 1) x y))))) +(define (tak27 x y z) + (cond ((not (< y x)) z) + (else (tak28 (tak36 (- x 1) y z) + (tak8 (- y 1) z x) + (tak76 (- z 1) x y))))) +(define (tak28 x y z) + (cond ((not (< y x)) z) + (else (tak29 (tak73 (- x 1) y z) + (tak19 (- y 1) z x) + (tak93 (- z 1) x y))))) +(define (tak29 x y z) + (cond ((not (< y x)) z) + (else (tak30 (tak10 (- x 1) y z) + (tak30 (- y 1) z x) + (tak10 (- z 1) x y))))) +(define (tak30 x y z) + (cond ((not (< y x)) z) + (else (tak31 (tak47 (- x 1) y z) + (tak41 (- y 1) z x) + (tak27 (- z 1) x y))))) +(define (tak31 x y z) + (cond ((not (< y x)) z) + (else (tak32 (tak84 (- x 1) y z) + (tak52 (- y 1) z x) + (tak44 (- z 1) x y))))) +(define (tak32 x y z) + (cond ((not (< y x)) z) + (else (tak33 (tak21 (- x 1) y z) + (tak63 (- y 1) z x) + (tak61 (- z 1) x y))))) +(define (tak33 x y z) + (cond ((not (< y x)) z) + (else (tak34 (tak58 (- x 1) y z) + (tak74 (- y 1) z x) + (tak78 (- z 1) x y))))) +(define (tak34 x y z) + (cond ((not (< y x)) z) + (else (tak35 (tak95 (- x 1) y z) + (tak85 (- y 1) z x) + (tak95 (- z 1) x y))))) +(define (tak35 x y z) + (cond ((not (< y x)) z) + (else (tak36 (tak32 (- x 1) y z) + (tak96 (- y 1) z x) + (tak12 (- z 1) x y))))) +(define (tak36 x y z) + (cond ((not (< y x)) z) + (else (tak37 (tak69 (- x 1) y z) + (tak7 (- y 1) z x) + (tak29 (- z 1) x y))))) +(define (tak37 x y z) + (cond ((not (< y x)) z) + (else (tak38 (tak6 (- x 1) y z) + (tak18 (- y 1) z x) + (tak46 (- z 1) x y))))) +(define (tak38 x y z) + (cond ((not (< y x)) z) + (else (tak39 (tak43 (- x 1) y z) + (tak29 (- y 1) z x) + (tak63 (- z 1) x y))))) +(define (tak39 x y z) + (cond ((not (< y x)) z) + (else (tak40 (tak80 (- x 1) y z) + (tak40 (- y 1) z x) + (tak80 (- z 1) x y))))) +(define (tak40 x y z) + (cond ((not (< y x)) z) + (else (tak41 (tak17 (- x 1) y z) + (tak51 (- y 1) z x) + (tak97 (- z 1) x y))))) +(define (tak41 x y z) + (cond ((not (< y x)) z) + (else (tak42 (tak54 (- x 1) y z) + (tak62 (- y 1) z x) + (tak14 (- z 1) x y))))) +(define (tak42 x y z) + (cond ((not (< y x)) z) + (else (tak43 (tak91 (- x 1) y z) + (tak73 (- y 1) z x) + (tak31 (- z 1) x y))))) +(define (tak43 x y z) + (cond ((not (< y x)) z) + (else (tak44 (tak28 (- x 1) y z) + (tak84 (- y 1) z x) + (tak48 (- z 1) x y))))) +(define (tak44 x y z) + (cond ((not (< y x)) z) + (else (tak45 (tak65 (- x 1) y z) + (tak95 (- y 1) z x) + (tak65 (- z 1) x y))))) +(define (tak45 x y z) + (cond ((not (< y x)) z) + (else (tak46 (tak2 (- x 1) y z) + (tak6 (- y 1) z x) + (tak82 (- z 1) x y))))) +(define (tak46 x y z) + (cond ((not (< y x)) z) + (else (tak47 (tak39 (- x 1) y z) + (tak17 (- y 1) z x) + (tak99 (- z 1) x y))))) +(define (tak47 x y z) + (cond ((not (< y x)) z) + (else (tak48 (tak76 (- x 1) y z) + (tak28 (- y 1) z x) + (tak16 (- z 1) x y))))) +(define (tak48 x y z) + (cond ((not (< y x)) z) + (else (tak49 (tak13 (- x 1) y z) + (tak39 (- y 1) z x) + (tak33 (- z 1) x y))))) +(define (tak49 x y z) + (cond ((not (< y x)) z) + (else (tak50 (tak50 (- x 1) y z) + (tak50 (- y 1) z x) + (tak50 (- z 1) x y))))) +(define (tak50 x y z) + (cond ((not (< y x)) z) + (else (tak51 (tak87 (- x 1) y z) + (tak61 (- y 1) z x) + (tak67 (- z 1) x y))))) +(define (tak51 x y z) + (cond ((not (< y x)) z) + (else (tak52 (tak24 (- x 1) y z) + (tak72 (- y 1) z x) + (tak84 (- z 1) x y))))) +(define (tak52 x y z) + (cond ((not (< y x)) z) + (else (tak53 (tak61 (- x 1) y z) + (tak83 (- y 1) z x) + (tak1 (- z 1) x y))))) +(define (tak53 x y z) + (cond ((not (< y x)) z) + (else (tak54 (tak98 (- x 1) y z) + (tak94 (- y 1) z x) + (tak18 (- z 1) x y))))) +(define (tak54 x y z) + (cond ((not (< y x)) z) + (else (tak55 (tak35 (- x 1) y z) + (tak5 (- y 1) z x) + (tak35 (- z 1) x y))))) +(define (tak55 x y z) + (cond ((not (< y x)) z) + (else (tak56 (tak72 (- x 1) y z) + (tak16 (- y 1) z x) + (tak52 (- z 1) x y))))) +(define (tak56 x y z) + (cond ((not (< y x)) z) + (else (tak57 (tak9 (- x 1) y z) + (tak27 (- y 1) z x) + (tak69 (- z 1) x y))))) +(define (tak57 x y z) + (cond ((not (< y x)) z) + (else (tak58 (tak46 (- x 1) y z) + (tak38 (- y 1) z x) + (tak86 (- z 1) x y))))) +(define (tak58 x y z) + (cond ((not (< y x)) z) + (else (tak59 (tak83 (- x 1) y z) + (tak49 (- y 1) z x) + (tak3 (- z 1) x y))))) +(define (tak59 x y z) + (cond ((not (< y x)) z) + (else (tak60 (tak20 (- x 1) y z) + (tak60 (- y 1) z x) + (tak20 (- z 1) x y))))) +(define (tak60 x y z) + (cond ((not (< y x)) z) + (else (tak61 (tak57 (- x 1) y z) + (tak71 (- y 1) z x) + (tak37 (- z 1) x y))))) +(define (tak61 x y z) + (cond ((not (< y x)) z) + (else (tak62 (tak94 (- x 1) y z) + (tak82 (- y 1) z x) + (tak54 (- z 1) x y))))) +(define (tak62 x y z) + (cond ((not (< y x)) z) + (else (tak63 (tak31 (- x 1) y z) + (tak93 (- y 1) z x) + (tak71 (- z 1) x y))))) +(define (tak63 x y z) + (cond ((not (< y x)) z) + (else (tak64 (tak68 (- x 1) y z) + (tak4 (- y 1) z x) + (tak88 (- z 1) x y))))) +(define (tak64 x y z) + (cond ((not (< y x)) z) + (else (tak65 (tak5 (- x 1) y z) + (tak15 (- y 1) z x) + (tak5 (- z 1) x y))))) +(define (tak65 x y z) + (cond ((not (< y x)) z) + (else (tak66 (tak42 (- x 1) y z) + (tak26 (- y 1) z x) + (tak22 (- z 1) x y))))) +(define (tak66 x y z) + (cond ((not (< y x)) z) + (else (tak67 (tak79 (- x 1) y z) + (tak37 (- y 1) z x) + (tak39 (- z 1) x y))))) +(define (tak67 x y z) + (cond ((not (< y x)) z) + (else (tak68 (tak16 (- x 1) y z) + (tak48 (- y 1) z x) + (tak56 (- z 1) x y))))) +(define (tak68 x y z) + (cond ((not (< y x)) z) + (else (tak69 (tak53 (- x 1) y z) + (tak59 (- y 1) z x) + (tak73 (- z 1) x y))))) +(define (tak69 x y z) + (cond ((not (< y x)) z) + (else (tak70 (tak90 (- x 1) y z) + (tak70 (- y 1) z x) + (tak90 (- z 1) x y))))) +(define (tak70 x y z) + (cond ((not (< y x)) z) + (else (tak71 (tak27 (- x 1) y z) + (tak81 (- y 1) z x) + (tak7 (- z 1) x y))))) +(define (tak71 x y z) + (cond ((not (< y x)) z) + (else (tak72 (tak64 (- x 1) y z) + (tak92 (- y 1) z x) + (tak24 (- z 1) x y))))) +(define (tak72 x y z) + (cond ((not (< y x)) z) + (else (tak73 (tak1 (- x 1) y z) + (tak3 (- y 1) z x) + (tak41 (- z 1) x y))))) +(define (tak73 x y z) + (cond ((not (< y x)) z) + (else (tak74 (tak38 (- x 1) y z) + (tak14 (- y 1) z x) + (tak58 (- z 1) x y))))) +(define (tak74 x y z) + (cond ((not (< y x)) z) + (else (tak75 (tak75 (- x 1) y z) + (tak25 (- y 1) z x) + (tak75 (- z 1) x y))))) +(define (tak75 x y z) + (cond ((not (< y x)) z) + (else (tak76 (tak12 (- x 1) y z) + (tak36 (- y 1) z x) + (tak92 (- z 1) x y))))) +(define (tak76 x y z) + (cond ((not (< y x)) z) + (else (tak77 (tak49 (- x 1) y z) + (tak47 (- y 1) z x) + (tak9 (- z 1) x y))))) +(define (tak77 x y z) + (cond ((not (< y x)) z) + (else (tak78 (tak86 (- x 1) y z) + (tak58 (- y 1) z x) + (tak26 (- z 1) x y))))) +(define (tak78 x y z) + (cond ((not (< y x)) z) + (else (tak79 (tak23 (- x 1) y z) + (tak69 (- y 1) z x) + (tak43 (- z 1) x y))))) +(define (tak79 x y z) + (cond ((not (< y x)) z) + (else (tak80 (tak60 (- x 1) y z) + (tak80 (- y 1) z x) + (tak60 (- z 1) x y))))) +(define (tak80 x y z) + (cond ((not (< y x)) z) + (else (tak81 (tak97 (- x 1) y z) + (tak91 (- y 1) z x) + (tak77 (- z 1) x y))))) +(define (tak81 x y z) + (cond ((not (< y x)) z) + (else (tak82 (tak34 (- x 1) y z) + (tak2 (- y 1) z x) + (tak94 (- z 1) x y))))) +(define (tak82 x y z) + (cond ((not (< y x)) z) + (else (tak83 (tak71 (- x 1) y z) + (tak13 (- y 1) z x) + (tak11 (- z 1) x y))))) +(define (tak83 x y z) + (cond ((not (< y x)) z) + (else (tak84 (tak8 (- x 1) y z) + (tak24 (- y 1) z x) + (tak28 (- z 1) x y))))) +(define (tak84 x y z) + (cond ((not (< y x)) z) + (else (tak85 (tak45 (- x 1) y z) + (tak35 (- y 1) z x) + (tak45 (- z 1) x y))))) +(define (tak85 x y z) + (cond ((not (< y x)) z) + (else (tak86 (tak82 (- x 1) y z) + (tak46 (- y 1) z x) + (tak62 (- z 1) x y))))) +(define (tak86 x y z) + (cond ((not (< y x)) z) + (else (tak87 (tak19 (- x 1) y z) + (tak57 (- y 1) z x) + (tak79 (- z 1) x y))))) +(define (tak87 x y z) + (cond ((not (< y x)) z) + (else (tak88 (tak56 (- x 1) y z) + (tak68 (- y 1) z x) + (tak96 (- z 1) x y))))) +(define (tak88 x y z) + (cond ((not (< y x)) z) + (else (tak89 (tak93 (- x 1) y z) + (tak79 (- y 1) z x) + (tak13 (- z 1) x y))))) +(define (tak89 x y z) + (cond ((not (< y x)) z) + (else (tak90 (tak30 (- x 1) y z) + (tak90 (- y 1) z x) + (tak30 (- z 1) x y))))) +(define (tak90 x y z) + (cond ((not (< y x)) z) + (else (tak91 (tak67 (- x 1) y z) + (tak1 (- y 1) z x) + (tak47 (- z 1) x y))))) +(define (tak91 x y z) + (cond ((not (< y x)) z) + (else (tak92 (tak4 (- x 1) y z) + (tak12 (- y 1) z x) + (tak64 (- z 1) x y))))) +(define (tak92 x y z) + (cond ((not (< y x)) z) + (else (tak93 (tak41 (- x 1) y z) + (tak23 (- y 1) z x) + (tak81 (- z 1) x y))))) +(define (tak93 x y z) + (cond ((not (< y x)) z) + (else (tak94 (tak78 (- x 1) y z) + (tak34 (- y 1) z x) + (tak98 (- z 1) x y))))) +(define (tak94 x y z) + (cond ((not (< y x)) z) + (else (tak95 (tak15 (- x 1) y z) + (tak45 (- y 1) z x) + (tak15 (- z 1) x y))))) +(define (tak95 x y z) + (cond ((not (< y x)) z) + (else (tak96 (tak52 (- x 1) y z) + (tak56 (- y 1) z x) + (tak32 (- z 1) x y))))) +(define (tak96 x y z) + (cond ((not (< y x)) z) + (else (tak97 (tak89 (- x 1) y z) + (tak67 (- y 1) z x) + (tak49 (- z 1) x y))))) +(define (tak97 x y z) + (cond ((not (< y x)) z) + (else (tak98 (tak26 (- x 1) y z) + (tak78 (- y 1) z x) + (tak66 (- z 1) x y))))) +(define (tak98 x y z) + (cond ((not (< y x)) z) + (else (tak99 (tak63 (- x 1) y z) + (tak89 (- y 1) z x) + (tak83 (- z 1) x y))))) +(define (tak99 x y z) + (cond ((not (< y x)) z) + (else (tak0 (tak0 (- x 1) y z) + (tak0 (- y 1) z x) + (tak0 (- z 1) x y))))) + +;;; call: (tak0 18 12 6) + +(time (tak0 18 12 2)) + diff --git a/collects/tests/mzscheme/benchmarks/common/takr.ss b/collects/tests/mzscheme/benchmarks/common/takr.ss new file mode 100644 index 0000000000..4c62598815 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/takr.ss @@ -0,0 +1,2 @@ + +(module takr "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/traverse.sch b/collects/tests/mzscheme/benchmarks/common/traverse.sch new file mode 100644 index 0000000000..7822ed8c5e --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/traverse.sch @@ -0,0 +1,158 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: traverse.sch +; Description: TRAVERSE benchmark +; Author: Richard Gabriel +; Created: 12-Apr-85 +; Modified: 12-Apr-85 10:24:04 (Bob Shaw) +; 9-Aug-87 (Will Clinger) +; Language: Scheme (but see note) +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Note: This benchmark may depend upon the empty list being the same +; as #f. + +;;; TRAVERSE -- Benchmark which creates and traverses a tree structure. + +(define (make-node) + (let ((node (make-vector 11 '()))) + (vector-set! node 0 'node) + (vector-set! node 3 (snb)) + node)) + +(define (node-parents node) (vector-ref node 1)) +(define (node-sons node) (vector-ref node 2)) +(define (node-sn node) (vector-ref node 3)) +(define (node-entry1 node) (vector-ref node 4)) +(define (node-entry2 node) (vector-ref node 5)) +(define (node-entry3 node) (vector-ref node 6)) +(define (node-entry4 node) (vector-ref node 7)) +(define (node-entry5 node) (vector-ref node 8)) +(define (node-entry6 node) (vector-ref node 9)) +(define (node-mark node) (vector-ref node 10)) + +(define (node-parents-set! node v) (vector-set! node 1 v)) +(define (node-sons-set! node v) (vector-set! node 2 v)) +(define (node-sn-set! node v) (vector-set! node 3 v)) +(define (node-entry1-set! node v) (vector-set! node 4 v)) +(define (node-entry2-set! node v) (vector-set! node 5 v)) +(define (node-entry3-set! node v) (vector-set! node 6 v)) +(define (node-entry4-set! node v) (vector-set! node 7 v)) +(define (node-entry5-set! node v) (vector-set! node 8 v)) +(define (node-entry6-set! node v) (vector-set! node 9 v)) +(define (node-mark-set! node v) (vector-set! node 10 v)) + +(define *sn* 0) +(define *rand* 21) +(define *count* 0) +(define *marker* #f) +(define *root* '()) + +(define (snb) + (set! *sn* (+ 1 *sn*)) + *sn*) + +(define (seed) + (set! *rand* 21) + *rand*) + +(define (traverse-random) + (set! *rand* (remainder (* *rand* 17) 251)) + *rand*) + +(define (traverse-remove n q) + (cond ((eq? (cdr (car q)) (car q)) + (let ((x (caar q))) (set-car! q #f) x)) + ((zero? n) + (let ((x (caar q))) + (do ((p (car q) (cdr p))) + ((eq? (cdr p) (car q)) + (set-cdr! p (cdr (car q))) + (set-car! q p))) + x)) + (else (do ((n n (- n 1)) + (q (car q) (cdr q)) + (p (cdr (car q)) (cdr p))) + ((zero? n) (let ((x (car q))) (set-cdr! q p) x)))))) + +(define (traverse-select n q) + (do ((n n (- n 1)) + (q (car q) (cdr q))) + ((zero? n) (car q)))) + +(define (add a q) + (cond ((null? q) + `(,(let ((x `(,a))) + (set-cdr! x x) x))) + ((null? (car q)) + (let ((x `(,a))) + (set-cdr! x x) + (set-car! q x) + q)) + ; the CL version had a useless set-car! in the next line (wc) + (else (set-cdr! (car q) `(,a . ,(cdr (car q)))) + q))) + +(define (create-structure n) + (let ((a `(,(make-node)))) + (do ((m (- n 1) (- m 1)) + (p a)) + ((zero? m) + (set! a `(,(begin (set-cdr! p a) p))) + (do ((unused a) + (used (add (traverse-remove 0 a) #f)) + (x 0) + (y 0)) + ((null? (car unused)) + (find-root (traverse-select 0 used) n)) + (set! x (traverse-remove (remainder (traverse-random) n) unused)) + (set! y (traverse-select (remainder (traverse-random) n) used)) + (add x used) + (node-sons-set! y `(,x . ,(node-sons y))) + (node-parents-set! x `(,y . ,(node-parents x))) )) + (set! a (cons (make-node) a))))) + +(define (find-root node n) + (do ((n n (- n 1))) + ((or (zero? n) (null? (node-parents node))) + node) + (set! node (car (node-parents node))))) + +(define (travers node mark) + (cond ((eq? (node-mark node) mark) #f) + (else (node-mark-set! node mark) + (set! *count* (+ 1 *count*)) + (node-entry1-set! node (not (node-entry1 node))) + (node-entry2-set! node (not (node-entry2 node))) + (node-entry3-set! node (not (node-entry3 node))) + (node-entry4-set! node (not (node-entry4 node))) + (node-entry5-set! node (not (node-entry5 node))) + (node-entry6-set! node (not (node-entry6 node))) + (do ((sons (node-sons node) (cdr sons))) + ((null? sons) #f) + (travers (car sons) mark))))) + +(define (traverse root) + (let ((*count* 0)) + (travers root (begin (set! *marker* (not *marker*)) *marker*)) + *count*)) + +(define (init-traverse) ; Changed from defmacro to defun \bs + (set! *root* (create-structure 100)) + #f) + +(define (run-traverse) ; Changed from defmacro to defun \bs + (do ((i 50 (- i 1))) + ((zero? i)) + (traverse *root*) + (traverse *root*) + (traverse *root*) + (traverse *root*) + (traverse *root*))) + +;;; to initialize, call: (init-traverse) +;;; to run traverse, call: (run-traverse) + +(time (init-traverse)) +(time (run-traverse)) + diff --git a/collects/tests/mzscheme/benchmarks/common/triangle.sch b/collects/tests/mzscheme/benchmarks/common/triangle.sch new file mode 100644 index 0000000000..53d54de1f3 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/triangle.sch @@ -0,0 +1,84 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; File: triangle.sch +; Description: TRIANGLE benchmark +; Author: Richard Gabriel +; Created: 12-Apr-85 +; Modified: 12-Apr-85 10:30:32 (Bob Shaw) +; 11-Aug-87 (Will Clinger) +; 22-Jan-88 (Will Clinger) +; Language: Scheme +; Status: Public Domain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; TRIANG -- Board game benchmark. + +(define *board* (make-vector 16 1)) +(define *sequence* (make-vector 14 0)) +(define *a* (make-vector 37)) +(for-each (lambda (i x) (vector-set! *a* i x)) + '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36) + '(1 2 4 3 5 6 1 3 6 2 5 4 11 12 + 13 7 8 4 4 7 11 8 12 13 6 10 + 15 9 14 13 13 14 15 9 10 + 6 6)) +(define *b* (make-vector 37)) +(for-each (lambda (i x) (vector-set! *b* i x)) + '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36) + '(2 4 7 5 8 9 3 6 10 5 9 8 + 12 13 14 8 9 5 2 4 7 5 8 + 9 3 6 10 5 9 8 12 13 14 + 8 9 5 5)) +(define *c* (make-vector 37)) +(for-each (lambda (i x) (vector-set! *c* i x)) + '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36) + '(4 7 11 8 12 13 6 10 15 9 14 13 + 13 14 15 9 10 6 1 2 4 3 5 6 1 + 3 6 2 5 4 11 12 13 7 8 4 4)) +(define *answer* '()) +(define *final* '()) +(vector-set! *board* 5 0) + +(define (last-position) + (do ((i 1 (+ i 1))) + ((or (= i 16) (= 1 (vector-ref *board* i))) + (if (= i 16) 0 i)))) + +(define (try i depth) + (cond ((= depth 14) + (let ((lp (last-position))) + (if (not (member lp *final*)) + (set! *final* (cons lp *final*)))) + (set! *answer* + (cons (cdr (vector->list *sequence*)) *answer*)) + #t) + ((and (= 1 (vector-ref *board* (vector-ref *a* i))) + (= 1 (vector-ref *board* (vector-ref *b* i))) + (= 0 (vector-ref *board* (vector-ref *c* i)))) + (vector-set! *board* (vector-ref *a* i) 0) + (vector-set! *board* (vector-ref *b* i) 0) + (vector-set! *board* (vector-ref *c* i) 1) + (vector-set! *sequence* depth i) + (do ((j 0 (+ j 1)) + (depth (+ depth 1))) + ((or (= j 36) (try j depth)) #f)) + (vector-set! *board* (vector-ref *a* i) 1) + (vector-set! *board* (vector-ref *b* i) 1) + (vector-set! *board* (vector-ref *c* i) 0) '()) + (else #f))) + +(define (gogogo i) + (let ((*answer* '()) + (*final* '())) + (try i 1))) + +;;; call: (gogogo 22)) + +(time (let loop ([n 10000]) + (if (zero? n) + 'done + (begin + (gogogo 22) + (loop (sub1 n)))))) diff --git a/collects/tests/mzscheme/benchmarks/common/triangle.ss b/collects/tests/mzscheme/benchmarks/common/triangle.ss new file mode 100644 index 0000000000..322de72563 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/triangle.ss @@ -0,0 +1,2 @@ + +(module triangle "wrap.ss") diff --git a/collects/tests/mzscheme/benchmarks/common/wrap.ss b/collects/tests/mzscheme/benchmarks/common/wrap.ss new file mode 100644 index 0000000000..be0d9d0af0 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/common/wrap.ss @@ -0,0 +1,7 @@ + +(module wrap mzscheme + (provide (rename module-begin #%module-begin)) + (require (lib "include.ss")) + (define-syntax (module-begin stx) + (let ([name (syntax-property stx 'enclosing-module-name)]) + #`(#%plain-module-begin (include #,(format "~a.sch" name)))))) diff --git a/collects/tests/mzscheme/benchmarks/mz/expand-class.scm b/collects/tests/mzscheme/benchmarks/mz/expand-class.scm new file mode 100644 index 0000000000..6a5c032113 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/mz/expand-class.scm @@ -0,0 +1,11 @@ + +(let ([dir (build-path (collection-path "mzlib") + "private")]) + (with-input-from-file (build-path dir "class-internal.ss") + (lambda () + (parameterize ([current-load-relative-directory dir]) + (let ([s (read-syntax)]) + (time (compile s))))))) + + + \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/mz/input.xml b/collects/tests/mzscheme/benchmarks/mz/input.xml new file mode 100644 index 0000000000..efef328d95 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/mz/input.xml @@ -0,0 +1,12 @@ +PLaneT Package Repository
nbsp
nbspnbsp[icon]
nbsp
PLaneT Package RepositoryPLTnbsp|nbspDrSchemenbsp|nbspTeachScheme!nbsp|nbspHtDPnbsp|nbspPLaneTnbspnbsp

PLaneT repository for PLT Scheme v299.x-3xx

PLaneT is PLT Scheme's centralized package distribution system. Here you will find user-contributed Scheme packages along with instructions for using them.

The packages on this site are user-contributed and not part of PLT Scheme. Be aware that when you download one of them for use in your programs, you are installing software on your computer that could deliberately or accidentally harm your system. Do not require from PLaneT any packages you do not trust.

For more about how to use PLaneT and for instructions on turning your own code into packages, look up PLaneT in the DrScheme Help Desk.

This page shows the latest versions of all available packages, sorted by category.

You can be notified when new packages are added by subscribing to the RSS feed or to the PLaneT-Announce mailing list.

Available Packages

Development Tools
nbspaspect-scheme.plt2 (2.1)cdutchynExtended reference implementation of AspectScheme
nbspcombinators.plt (1.3)cceUseful, higher-order functions.
nbspinstaweb.plt1.4 (1.4)schematicsA wrapper to setup and run the web-server +and servlets
nbspjava.plt0.1 (1.4)dhermanA library for manipulating Java programs in both source and binary format.
nbspjavascript.plt0.4 (2.3)dhermanA DrScheme language level for the JavaScript programming language.
nbspmacro.plt1.0 (1.0)schematicsA library of macros that implement common patterns.
nbspmrmathematica.plt (1.2)zckMrMathematica -- Union of Mathematica and Scheme.
nbspnamespace.plt1.0 (1.0)schematicsA library of useful procedures on namespaces
nbspno-brainer.plt (1.0)clementsA simple static checker that reports some local arity errors and unused bindings
nbspparameter-utils.plt (1.0)cceParameterization utilities.
nbspport.plt1.0 (1.0)schematicsA library of functions that operate on ports.
nbsprequire.plt1.0 (1.0)ryancRequire is a library that lets one name external modules or packages and use short abbreviations for requiring those external modules or packages. In addition, it provides a single point of specification for the location and version number of the packages being used.
nbsproos.plt1.40 (1.4)oesterholtROOS is an OO Framework this is used with mzgtk2 and Persistent ROOS
nbspschemeunit.plt3.1 (2.1)schematicsSchemeUnit is a unit testing framework based on the Extreme Programming unit test frameworks
nbspstylesheet.plt0.1 (1.0)soegaardA DrScheme language level for writing Cascading Style Sheets (CSS).
nbspsyntax-browser.plt2.0 (2.0)ryancThe syntax-browser displays lexical context and hygiene information on syntax objects using colors and highlighting.
nbspsyntax-utils.plt (1.0)cceSyntax and macro utilities.
nbsptest.plt1 (1.2)dhermanUtilities for unit testing.
nbsptesteez.plt0.3 (1.1)neilTesteez: Lightweight Unit Test Mechanism for R5RS Scheme
Networking and Protocols
nbspbencode.plt0.1 (1.0)neilbencode.scm: BitTorrent Bencode Decoding in Scheme
nbspblogue.plt (1.1)jaymccarthyblogging tool like early blosxom
nbsphtmlprag.plt0.16 (1.3)neilHtmlPrag: Pragmatic Parsing and Emitting of HTML using SXML and SHTML
nbspmail-parse.plt0.2 (1.1)mburnsParse an email, or a stream of emails, into a simple structure
nbspresume.plt (3.0)jacobmGives a simple API that allows PLT Web Server servlet programmers to create user accounts that let users resume old sessions after logging in
nbsprfc3339.plt0.2 (1.0)neilrfc3339.scm: RFC3339 Date and Time Format in Scheme
nbspspgsql.plt4.0 (1.2)schematicsThe spgsql library provides classes, datatypes, and procedures useful for connecting to a PostgreSQL database server over TCP.
nbspurl-param.plt (1.3)jaymccarthyStores Web cells in URLs
nbspwebbot.plt1.30 (1.3)oesterholtWebBot contains a couple of ROOS classes that provide functionality to post multipart/form-data to sites.
nbspwtk.plt (1.3)jaymccarthySome web components
nbspxhtml.plt1 (1.1)dhermanUtilities for generating XHTML content in a servlet.
nbspxmlrpc.plt1.0 (1.1)schematicsImplementation of the XML-RPC protocol.
Graphics and Audio
nbspallegro.plt0.1 (1.0)kazzmirBindings to the Allegro Game Programming Library
nbspcairo.plt (1.0)samthA set of bindings for the cairo [http://cairographics.org] drawing library.Currently the font handling functionality is not included in the binding.
nbspiTunes-helper.pltthe only version (1.0)clementsA nearly useless package to help you choose subsets of your iTunes Library useful for randomizing what's on your iPod.
nbsprsitunes.plt (1.1)jaymccarthyHelps you use iTunes to care for your RSI.
nbspx11.plt0.1 (1.0)kazzmirBindings to the X11 library
XML-Related
nbspcsv.plt0.5 (1.1)neilcsv.scm: Comma-Separated Value (CSV) Utilities in Scheme
nbspssax.plt (1.3)lizorkinSSAX functional XML parsing framework to inter-convert between an angular-bracket and an S-expression-based notations for markup documents
nbspsxml-match.plt1.0 (1.0)jimA 'by-example' pattern matcher for SXML http://celtic.benderweb.net/sxml-match/
nbspsxml.plt (1.4)lizorkinCollection of tools for processing markup documents in the form of S-expressions
nbspwebit.plt2.0 (1.4)jimA system for authoring and transforming XML in Scheme. http://celtic.benderweb.net/webit/
nbspwebscraperhelper.plt0.3 (1.0)neilWebScraperHelper: Simple Generation of SXPath Queries from SXML Examples
nbspwebsite.plt (1.0)cceWebsite creation functions.
Data Structures and Algorithms
nbspahocorasick.plt (1.0)dyooAho-Corasick Tools: both an interpreter and a compiler for Aho-Corasick automata
nbspaterm.plt1 (2.0)dhermanUtilities for the ATerm format.
nbspenvironment.plt3.0 (3.0)cobbeA rib-cage environment data structure. (For PLT lt 301.7, use + version 1.)
nbspequiv.plt (1.0)cceExtensible Recursive Equivalence Relations.
nbspevector.plt1.0 (1.0)soegaardExtensible vectors are a low level, resizeable data structure resembling normal Scheme vectors.
nbspgalore.plt (3.3)soegaardA library of functional data structures. Version 3 is currently beta software. Use Galore version 2 for most purposes.
nbsplevenshtein.plt0.4 (1.1)neillevenshtein.scm: Levenshtein Distance Metric in Scheme
nbsplist.plt1 (1.0)dhermanCombines the best of the standard mzscheme list libraries.
nbspstruct.plt4 (2.1)dhermanA library of various data structures based on structs, including algebraic datatypes and inheritance hierarchies.
nbspsuffixtree.plt (1.1)dyooLinear-time construction of suffix trees using Ukkonen's Algorithm
nbsptrie.plt (1.0)jaymccarthyFinite maps as big-endian binary tries
nbspzipper.plt (1.0)jaymccarthyZipper-like functions.
Input/Output and Filesystem
nbspbit-io.plt1 (1.0)soegaardBit IO

This package provides the operations for reading and writing bits from and to files.

nbspical.plt (1.2)jaymccarthyReads and writes iCal/vCal files
nbspio.plt3 (1.6)dhermanA library of I/O and filesystem utilities.
nbsppprint.plt1 (1.0)dhermanA pretty-printing library.
nbspscripting.plt1.0 (1.0)ryancScripting is a library of procedures useful for writing mzscheme scripts, especially those which execute external commands and manipulate the filesystem.
nbspsql-oo.plt (2.0)jaymccarthyAllows persistent objects in an SQL database. (Currently only works with SQLite.)
nbspsqlite.plt (3.1)jaymccarthyAllows access to SQLite databases.
nbspzip.plt2 (2.1)dhermanA library of utilities for manipulating zip files.
Mathematical and Scientific
nbspscience.plt2.2.1 (2.4)williamsA collection of modules that provide functions for numerical computing.
nbspsimulation.plt2.0 (2.0)williamsImplements an integrated discrete event and continuous simulation engine.
Hardware/Operating System-Specific Tools
nbsplinux-proc-apm.plt0.2 (1.0)neillinux-proc-apm.scm: Linux /proc/apm APM Data Access in Scheme
nbsppassword.plt1.0 (1.0)schematicsA library of functions to generate passwords.
Textual and Graphical User Interface
nbspwidgets.plt2 (2.0)dhermanA library of GUI widgets.
Metaprogramming
nbspmacro-object.plt1 (1.0)dhermanA library for attaching elaboration-time values to syntax transformers.
nbspredex.plt (2.2)robby
A domain-specific language for context-sensitive reduction semantics. Put in a specification and get out a stepper.
PLaneT-Related
nbsptest-connection.plt (1.0)planetTests your PLaneT collection to make sure it's working properly.
Miscellaneous
nbspSET.plt (1.0)jaymccarthySET
nbspbisect-search.plt1.0 (1.0)dyooBisection search algorithm
nbspccnum.plt0.2 (1.0)neilccnum.scm: Credit Card Number Utilities in Scheme
nbspcdrswift.plt (1.5)dignatofSlideshoW Including FrTime
nbspclassic-java.plt1.1 (1.1)cobbeAn implementation of ClassicJava in PLT Redex.
nbspcontract-utils.plt3.0 (3.0)cobbeVarious contract functions and utilities.
nbspcontrol.plt1 (1.0)soegaardControl Structures

This package provides the control structures while, until, dotimes, and tagged-begin. The tagged-begin contruct is a 'begin with labels and goto'.

nbspcsv-write.plt1 (1.2)dhermanGenerates CSV-formatted output.
nbspdatastructs.plt0.40 (1.0)oesterholtDatastructs - Thread Safe Datastructures
nbspfortunedb.plt (1.0)jaymccarthyFortune Database
nbspgenerator.plt1.0 (2.0)dyooProvides nice syntactic sugar for writing Python/Ruby stylegenerators.
nbspgeocoder.plt1 (1.1)dhermanGeocodes US street addresses.
nbspgrid.plt (1.1)jaymccarthyManaging your life is good for you.
nbsphash-store.plt (1.2)jaymccarthyStores bytes by SHA1 hash.
nbspho-utils.plt1.00 (1.0)oesterholtHO Utils - are utilities that are used with various packages
nbspinspector.plt2 (1.0)dhermanA library of inspector utilities.
nbspjavascript.plt (1.0)jaymccarthyJavascript s-expression syntax
nbspmemoize.plt2 (2.0)dhermanMacros for defining memoized procedures.
nbspmeta-q.plt (1.0)jaymccarthyMeta-Q implementation for PLT strings
nbspmmss.plt (1.0)jaymccarthyJay McCarthy's collection of Scheme procedures.
nbspmysqldump.plt1 (1.0)dhermanConverts a MySQL dump to CSV.
nbspnationality.plt1 (3.0)dhermanMaps country names to their nationalities.
nbspnumspell.plt0.1 (1.0)neilnumspell.scm: Spelling Numbers as English in Scheme
nbsppostnet-planet.plt0.2 (1.0)neilpostnet.scm: USPS POSTNET Barcode Encoding in Scheme
nbspprefix.plt (1.1)jaymccarthyTests students with regards to the use of prefix notation.
nbspprophecy.plt1 (1.0)dhermanA "future-generator" control construct, or "prophecy."
nbspprotobj.plt0.2 (1.0)neilProtobj: Prototype-Delegation Object Model in Scheme
nbsproman.plt0.1 (1.0)amsUtility functions for roman numerals.
nbspsqlid.plt1.01 (1.2)oesterholtSQLI/SQLD is a framework for RDBM access.SQLD drivers are provided for SQLite3, PostgreSQL8, MySQL5, Oraclegt=8 and DB2gt=8
nbspsrfi.plt1 (1.1)soegaardSRFI Extensions and SRFI Drafts

SRFI 42 Eager comprehensions extended with the generators :match, :plt-match, :let-value, :pairs, :do-until, and more

SRFI 78 Draft Lightweight testing (pr 18-jan-2006)

nbspsyntax.plt1 (1.0)soegaardPretty printing of expanded syntax. Provides unexpand and pp-syntax.
nbsptabexpand.plt0.2 (1.0)neiltabexpand.scm: Tab Character Expansion in Scheme
nbsptail.plt1 (1.0)dhermanA special form for capturing a tail-context-preserving continuation.
nbspwith-bindings.plt (1.2)jaymccarthyA convenient syntax for servlets.
nbspxml-pull.plt1.0 (1.0)dyoopull-style parsing for very large xml documents.
nbspxxexpr.plt1.0 (1.0)lshiftA library of writing functions for SXML.
nbspyppdb.plt (2.0)jaymccarthyOrganizes your paper collection.

Available Packages: Detail

Development Tools

aspect-scheme.plt contributed by cdutchynnbsp[library home page]
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (2.1)
(require (planet "aspect-scheme2.ss" ("cdutchyn" "aspect-scheme.plt" 2 1)))

Extended reference implementation of AspectScheme
combinators.plt contributed by cce
documentationnbsp-nbsplatest package version: (1.3)
(require (planet "combinators.ss" ("cce" "combinators.plt" 1 3)))

Useful, higher-order functions.
instaweb.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.4nbsp-nbsplatest package version: (1.4)
(require (planet "instaweb.ss" ("schematics" "instaweb.plt" 1 4)))

A wrapper to setup and run the web-server +and servlets
java.plt contributed by dherman
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.4)
(require (planet "java.ss" ("dherman" "java.plt" 1 4)))

A library for manipulating Java programs in both source and binary format.
javascript.plt contributed by dherman
documentationnbsp-nbsplatest version: 0.4nbsp-nbsplatest package version: (2.3)
(require (planet "tool.ss" ("dherman" "javascript.plt" 2 3)))

A DrScheme language level for the JavaScript programming language.
macro.plt contributed by schematicsnbsp[library home page]
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "macro.ss" ("schematics" "macro.plt" 1 0)))

A library of macros that implement common patterns.
mrmathematica.plt contributed by zcknbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "mathematica.ss" ("zck" "mrmathematica.plt" 1 2)))

MrMathematica -- Union of Mathematica and Scheme.
namespace.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "namespace.ss" ("schematics" "namespace.plt" 1 0)))

A library of useful procedures on namespaces
no-brainer.plt contributed by clements
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("clements" "no-brainer.plt" 1 0)))

A simple static checker that reports some local arity errors and unused bindings
parameter-utils.plt contributed by cce
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "parameter-utils.ss" ("cce" "parameter-utils.plt" 1 0)))

Parameterization utilities.
port.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "port.ss" ("schematics" "port.plt" 1 0)))

A library of functions that operate on ports.
require.plt contributed by ryanc
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("ryanc" "require.plt" 1 0)))

Require is a library that lets one name external modules or packages and use short abbreviations for requiring those external modules or packages. In addition, it provides a single point of specification for the location and version number of the packages being used.
roos.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 1.40nbsp-nbsplatest package version: (1.4)
(require (planet "[file]" ("oesterholt" "roos.plt" 1 4)))

ROOS is an OO Framework this is used with mzgtk2 and Persistent ROOS
schemeunit.plt contributed by schematics
documentationnbsp-nbsplatest version: 3.1nbsp-nbsplatest package version: (2.1)
(require (planet "test.ss" ("schematics" "schemeunit.plt" 2 1)))

SchemeUnit is a unit testing framework based on the Extreme Programming unit test frameworks
stylesheet.plt contributed by soegaard
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "tool.ss" ("soegaard" "stylesheet.plt" 1 0)))

A DrScheme language level for writing Cascading Style Sheets (CSS).
syntax-browser.plt contributed by ryanc
documentationnbsp-nbsplatest version: 2.0nbsp-nbsplatest package version: (2.0)
(require (planet "syntax-browser.ss" ("ryanc" "syntax-browser.plt" 2 0)))

The syntax-browser displays lexical context and hygiene information on syntax objects using colors and highlighting.
syntax-utils.plt contributed by cce
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "syntax-utils.ss" ("cce" "syntax-utils.plt" 1 0)))

Syntax and macro utilities.
test.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.2)
(require (planet "test.ss" ("dherman" "test.plt" 1 2)))

Utilities for unit testing.
testeez.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.3nbsp-nbsplatest package version: (1.1)
(require (planet "testeez.ss" ("neil" "testeez.plt" 1 1)))

Testeez: Lightweight Unit Test Mechanism for R5RS Scheme

Networking and Protocols

bencode.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "bencode.ss" ("neil" "bencode.plt" 1 0)))

bencode.scm: BitTorrent Bencode Decoding in Scheme
blogue.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "blogue-main.ss" ("jaymccarthy" "blogue.plt" 1 1)))

blogging tool like early blosxom
htmlprag.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.16nbsp-nbsplatest package version: (1.3)
(require (planet "htmlprag.ss" ("neil" "htmlprag.plt" 1 3)))

HtmlPrag: Pragmatic Parsing and Emitting of HTML using SXML and SHTML
instaweb.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.4nbsp-nbsplatest package version: (1.4)
(require (planet "instaweb.ss" ("schematics" "instaweb.plt" 1 4)))

A wrapper to setup and run the web-server +and servlets
mail-parse.plt contributed by mburnsnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.1)
(require (planet "mail-parse.ss" ("mburns" "mail-parse.plt" 1 1)))

Parse an email, or a stream of emails, into a simple structure
resume.plt contributed by jacobmnbsp[library home page]
documentationnbsp-nbsplatest package version: (3.0)
(require (planet "resume.ss" ("jacobm" "resume.plt" 3 0)))

Gives a simple API that allows PLT Web Server servlet programmers to create user accounts that let users resume old sessions after logging in
rfc3339.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "rfc3339.ss" ("neil" "rfc3339.plt" 1 0)))

rfc3339.scm: RFC3339 Date and Time Format in Scheme
spgsql.plt contributed by schematicsnbsp[library home page]
documentationnbsp-nbsplatest version: 4.0nbsp-nbsplatest package version: (1.2)
(require (planet "spgsql.ss" ("schematics" "spgsql.plt" 1 2)))

The spgsql library provides classes, datatypes, and procedures useful for connecting to a PostgreSQL database server over TCP.
url-param.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.3)
(require (planet "url-param.ss" ("jaymccarthy" "url-param.plt" 1 3)))

Stores Web cells in URLs
webbot.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 1.30nbsp-nbsplatest package version: (1.3)
(require (planet "[file]" ("oesterholt" "webbot.plt" 1 3)))

WebBot contains a couple of ROOS classes that provide functionality to post multipart/form-data to sites.
wtk.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.3)
(require (planet "wtk.ss" ("jaymccarthy" "wtk.plt" 1 3)))

Some web components
xhtml.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.1)
(require (planet "xhtml.ss" ("dherman" "xhtml.plt" 1 1)))

Utilities for generating XHTML content in a servlet.
xmlrpc.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.1)
(require (planet "xmlrpc.ss" ("schematics" "xmlrpc.plt" 1 1)))

Implementation of the XML-RPC protocol.

Graphics and Audio

allegro.plt contributed by kazzmir
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "util.ss" ("kazzmir" "allegro.plt" 1 0)))

Bindings to the Allegro Game Programming Library
cairo.plt contributed by samth
[no documentation available]nbsp-nbsplatest package version: (1.0)
(require (planet "cairo.ss" ("samth" "cairo.plt" 1 0)))

A set of bindings for the cairo [http://cairographics.org] drawing library.Currently the font handling functionality is not included in the binding.
iTunes-helper.plt contributed by clements
documentationnbsp-nbsplatest version: the only versionnbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("clements" "iTunes-helper.plt" 1 0)))

A nearly useless package to help you choose subsets of your iTunes Library useful for randomizing what's on your iPod.
mrmathematica.plt contributed by zcknbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "mathematica.ss" ("zck" "mrmathematica.plt" 1 2)))

MrMathematica -- Union of Mathematica and Scheme.
rsitunes.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "rsitunes.ss" ("jaymccarthy" "rsitunes.plt" 1 1)))

Helps you use iTunes to care for your RSI.
x11.plt contributed by kazzmir
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "x11.ss" ("kazzmir" "x11.plt" 1 0)))

Bindings to the X11 library

XML-Related

csv.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.5nbsp-nbsplatest package version: (1.1)
(require (planet "csv.ss" ("neil" "csv.plt" 1 1)))

csv.scm: Comma-Separated Value (CSV) Utilities in Scheme
htmlprag.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.16nbsp-nbsplatest package version: (1.3)
(require (planet "htmlprag.ss" ("neil" "htmlprag.plt" 1 3)))

HtmlPrag: Pragmatic Parsing and Emitting of HTML using SXML and SHTML
ssax.plt contributed by lizorkin
documentationnbsp-nbsplatest package version: (1.3)
(require (planet "ssax.ss" ("lizorkin" "ssax.plt" 1 3)))

SSAX functional XML parsing framework to inter-convert between an angular-bracket and an S-expression-based notations for markup documents
sxml-match.plt contributed by jimnbsp[library home page]
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "sxml-match.ss" ("jim" "sxml-match.plt" 1 0)))

A 'by-example' pattern matcher for SXML http://celtic.benderweb.net/sxml-match/
sxml.plt contributed by lizorkinnbsp[library home page]
documentationnbsp-nbsplatest package version: (1.4)
(require (planet "sxml.ss" ("lizorkin" "sxml.plt" 1 4)))

Collection of tools for processing markup documents in the form of S-expressions
webit.plt contributed by jimnbsp[library home page]
documentationnbsp-nbsplatest version: 2.0nbsp-nbsplatest package version: (1.4)
(require (planet "xml.ss" ("jim" "webit.plt" 1 4)))

A system for authoring and transforming XML in Scheme. http://celtic.benderweb.net/webit/
webscraperhelper.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.3nbsp-nbsplatest package version: (1.0)
(require (planet "webscraperhelper.ss" ("neil" "webscraperhelper.plt" 1 0)))

WebScraperHelper: Simple Generation of SXPath Queries from SXML Examples
website.plt contributed by cce
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "website.ss" ("cce" "website.plt" 1 0)))

Website creation functions.

Data Structures and Algorithms

ahocorasick.plt contributed by dyoo
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("dyoo" "ahocorasick.plt" 1 0)))

Aho-Corasick Tools: both an interpreter and a compiler for Aho-Corasick automata
aterm.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (2.0)
(require (planet "aterm.ss" ("dherman" "aterm.plt" 2 0)))

Utilities for the ATerm format.
environment.plt contributed by cobbe
documentationnbsp-nbsplatest version: 3.0nbsp-nbsplatest package version: (3.0)
(require (planet "environment.ss" ("cobbe" "environment.plt" 3 0)))

A rib-cage environment data structure. (For PLT lt 301.7, use + version 1.)
equiv.plt contributed by cce
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "equiv.ss" ("cce" "equiv.plt" 1 0)))

Extensible Recursive Equivalence Relations.
evector.plt contributed by soegaard
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "evector.scm" ("soegaard" "evector.plt" 1 0)))

Extensible vectors are a low level, resizeable data structure resembling normal Scheme vectors.
galore.plt contributed by soegaard
documentationnbsp-nbsplatest package version: (3.3)
(require (planet "[bag.ss|set.ss|table.ss]" ("soegaard" "galore.plt" 3 3)))

A library of functional data structures. Version 3 is currently beta software. Use Galore version 2 for most purposes.
levenshtein.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.4nbsp-nbsplatest package version: (1.1)
(require (planet "levenshtein.ss" ("neil" "levenshtein.plt" 1 1)))

levenshtein.scm: Levenshtein Distance Metric in Scheme
list.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "list.ss" ("dherman" "list.plt" 1 0)))

Combines the best of the standard mzscheme list libraries.
struct.plt contributed by dherman
documentationnbsp-nbsplatest version: 4nbsp-nbsplatest package version: (2.1)
(require (planet "datatype.ss" ("dherman" "struct.plt" 2 1)))

A library of various data structures based on structs, including algebraic datatypes and inheritance hierarchies.
suffixtree.plt contributed by dyoo
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "suffixtree.ss" ("dyoo" "suffixtree.plt" 1 1)))

Linear-time construction of suffix trees using Ukkonen's Algorithm
trie.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "fmap.ss" ("jaymccarthy" "trie.plt" 1 0)))

Finite maps as big-endian binary tries
zipper.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "zip.ss" ("jaymccarthy" "zipper.plt" 1 0)))

Zipper-like functions.

Input/Output and Filesystem

bit-io.plt contributed by soegaard
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "bit-io.scm" ("soegaard" "bit-io.plt" 1 0)))

Bit IO

This package provides the operations for reading and writing bits from and to files.

csv.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.5nbsp-nbsplatest package version: (1.1)
(require (planet "csv.ss" ("neil" "csv.plt" 1 1)))

csv.scm: Comma-Separated Value (CSV) Utilities in Scheme
ical.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "ical.ss" ("jaymccarthy" "ical.plt" 1 2)))

Reads and writes iCal/vCal files
io.plt contributed by dherman
documentationnbsp-nbsplatest version: 3nbsp-nbsplatest package version: (1.6)
(require (planet "io.ss" ("dherman" "io.plt" 1 6)))

A library of I/O and filesystem utilities.
port.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "port.ss" ("schematics" "port.plt" 1 0)))

A library of functions that operate on ports.
pprint.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "pprint.ss" ("dherman" "pprint.plt" 1 0)))

A pretty-printing library.
scripting.plt contributed by ryanc
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("ryanc" "scripting.plt" 1 0)))

Scripting is a library of procedures useful for writing mzscheme scripts, especially those which execute external commands and manipulate the filesystem.
sql-oo.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (2.0)
(require (planet "sql-oo.ss" ("jaymccarthy" "sql-oo.plt" 2 0)))

Allows persistent objects in an SQL database. (Currently only works with SQLite.)
sqlite.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (3.1)
(require (planet "sqlite.ss" ("jaymccarthy" "sqlite.plt" 3 1)))

Allows access to SQLite databases.
zip.plt contributed by dherman
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (2.1)
(require (planet "unzip.ss" ("dherman" "zip.plt" 2 1)))

A library of utilities for manipulating zip files.

Mathematical and Scientific

levenshtein.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.4nbsp-nbsplatest package version: (1.1)
(require (planet "levenshtein.ss" ("neil" "levenshtein.plt" 1 1)))

levenshtein.scm: Levenshtein Distance Metric in Scheme
mrmathematica.plt contributed by zcknbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "mathematica.ss" ("zck" "mrmathematica.plt" 1 2)))

MrMathematica -- Union of Mathematica and Scheme.
science.plt contributed by williams
documentationnbsp-nbsplatest version: 2.2.1nbsp-nbsplatest package version: (2.4)
(require (planet "science-with-graphics.ss" ("williams" "science.plt" 2 4)))

A collection of modules that provide functions for numerical computing.
simulation.plt contributed by williams
documentationnbsp-nbsplatest version: 2.0nbsp-nbsplatest package version: (2.0)
(require (planet "simulation-with-graphics.ss" ("williams" "simulation.plt" 2 0)))

Implements an integrated discrete event and continuous simulation engine.

Hardware/Operating System-Specific Tools

cairo.plt contributed by samth
[no documentation available]nbsp-nbsplatest package version: (1.0)
(require (planet "cairo.ss" ("samth" "cairo.plt" 1 0)))

A set of bindings for the cairo [http://cairographics.org] drawing library.Currently the font handling functionality is not included in the binding.
linux-proc-apm.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "linux-proc-apm.ss" ("neil" "linux-proc-apm.plt" 1 0)))

linux-proc-apm.scm: Linux /proc/apm APM Data Access in Scheme
password.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "password.ss" ("schematics" "password.plt" 1 0)))

A library of functions to generate passwords.

Textual and Graphical User Interface

pprint.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "pprint.ss" ("dherman" "pprint.plt" 1 0)))

A pretty-printing library.
widgets.plt contributed by dherman
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (2.0)
(require (planet "widgets.ss" ("dherman" "widgets.plt" 2 0)))

A library of GUI widgets.

Metaprogramming

aspect-scheme.plt contributed by cdutchynnbsp[library home page]
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (2.1)
(require (planet "aspect-scheme2.ss" ("cdutchyn" "aspect-scheme.plt" 2 1)))

Extended reference implementation of AspectScheme
java.plt contributed by dherman
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.4)
(require (planet "java.ss" ("dherman" "java.plt" 1 4)))

A library for manipulating Java programs in both source and binary format.
macro-object.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "macro-object.ss" ("dherman" "macro-object.plt" 1 0)))

A library for attaching elaboration-time values to syntax transformers.
namespace.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "namespace.ss" ("schematics" "namespace.plt" 1 0)))

A library of useful procedures on namespaces
pprint.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "pprint.ss" ("dherman" "pprint.plt" 1 0)))

A pretty-printing library.
redex.plt contributed by robbynbsp[library home page]
documentationnbsp-nbsplatest package version: (2.2)
(require (planet "[file]" ("robby" "redex.plt" 2 2)))

A domain-specific language for context-sensitive reduction semantics. Put in a specification and get out a stepper.
roos.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 1.40nbsp-nbsplatest package version: (1.4)
(require (planet "[file]" ("oesterholt" "roos.plt" 1 4)))

ROOS is an OO Framework this is used with mzgtk2 and Persistent ROOS
syntax-browser.plt contributed by ryanc
documentationnbsp-nbsplatest version: 2.0nbsp-nbsplatest package version: (2.0)
(require (planet "syntax-browser.ss" ("ryanc" "syntax-browser.plt" 2 0)))

The syntax-browser displays lexical context and hygiene information on syntax objects using colors and highlighting.

PLaneT-Related

require.plt contributed by ryanc
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("ryanc" "require.plt" 1 0)))

Require is a library that lets one name external modules or packages and use short abbreviations for requiring those external modules or packages. In addition, it provides a single point of specification for the location and version number of the packages being used.
test-connection.plt contributed by planet
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "test-connection.ss" ("planet" "test-connection.plt" 1 0)))

Tests your PLaneT collection to make sure it's working properly.

Miscellaneous

SET.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "servlet.ss" ("jaymccarthy" "SET.plt" 1 0)))

SET
bisect-search.plt contributed by dyoonbsp[library home page]
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "bisect-search.ss" ("dyoo" "bisect-search.plt" 1 0)))

Bisection search algorithm
blogue.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "blogue-main.ss" ("jaymccarthy" "blogue.plt" 1 1)))

blogging tool like early blosxom
ccnum.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "ccnum.ss" ("neil" "ccnum.plt" 1 0)))

ccnum.scm: Credit Card Number Utilities in Scheme
cdrswift.plt contributed by dignatof
documentationnbsp-nbsplatest package version: (1.5)
(require (planet "slideshow.ss" ("dignatof" "cdrswift.plt" 1 5)))

SlideshoW Including FrTime
classic-java.plt contributed by cobbe
documentationnbsp-nbsplatest version: 1.1nbsp-nbsplatest package version: (1.1)
(require (planet "classic-java.ss" ("cobbe" "classic-java.plt" 1 1)))

An implementation of ClassicJava in PLT Redex.
contract-utils.plt contributed by cobbe
documentationnbsp-nbsplatest version: 3.0nbsp-nbsplatest package version: (3.0)
(require (planet "contract-utils.ss" ("cobbe" "contract-utils.plt" 3 0)))

Various contract functions and utilities.
control.plt contributed by soegaard
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "control.scm" ("soegaard" "control.plt" 1 0)))

Control Structures

This package provides the control structures while, until, dotimes, and tagged-begin. The tagged-begin contruct is a 'begin with labels and goto'.

csv-write.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.2)
(require (planet "csv-write.ss" ("dherman" "csv-write.plt" 1 2)))

Generates CSV-formatted output.
datastructs.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 0.40nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("oesterholt" "datastructs.plt" 1 0)))

Datastructs - Thread Safe Datastructures
fortunedb.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "fortunedb.ss" ("jaymccarthy" "fortunedb.plt" 1 0)))

Fortune Database
generator.plt contributed by dyoonbsp[library home page]
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (2.0)
(require (planet "generator.ss" ("dyoo" "generator.plt" 2 0)))

Provides nice syntactic sugar for writing Python/Ruby stylegenerators.
geocoder.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.1)
(require (planet "geocoder.ss" ("dherman" "geocoder.plt" 1 1)))

Geocodes US street addresses.
grid.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "servlet.ss" ("jaymccarthy" "grid.plt" 1 1)))

Managing your life is good for you.
hash-store.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "hash-store.ss" ("jaymccarthy" "hash-store.plt" 1 2)))

Stores bytes by SHA1 hash.
ho-utils.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 1.00nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("oesterholt" "ho-utils.plt" 1 0)))

HO Utils - are utilities that are used with various packages
inspector.plt contributed by dherman
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (1.0)
(require (planet "inspector.ss" ("dherman" "inspector.plt" 1 0)))

A library of inspector utilities.
javascript.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "javascript.ss" ("jaymccarthy" "javascript.plt" 1 0)))

Javascript s-expression syntax
memoize.plt contributed by dherman
documentationnbsp-nbsplatest version: 2nbsp-nbsplatest package version: (2.0)
(require (planet "memoize.ss" ("dherman" "memoize.plt" 2 0)))

Macros for defining memoized procedures.
meta-q.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "meta-q.ss" ("jaymccarthy" "meta-q.plt" 1 0)))

Meta-Q implementation for PLT strings
mmss.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.0)
(require (planet "mmss.ss" ("jaymccarthy" "mmss.plt" 1 0)))

Jay McCarthy's collection of Scheme procedures.
mysqldump.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "csv-write.ss" ("dherman" "mysqldump.plt" 1 0)))

Converts a MySQL dump to CSV.
nationality.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (3.0)
(require (planet "nationality.ss" ("dherman" "nationality.plt" 3 0)))

Maps country names to their nationalities.
numspell.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "numspell.ss" ("neil" "numspell.plt" 1 0)))

numspell.scm: Spelling Numbers as English in Scheme
password.plt contributed by schematics
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "password.ss" ("schematics" "password.plt" 1 0)))

A library of functions to generate passwords.
postnet-planet.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "postnet.ss" ("neil" "postnet-planet.plt" 1 0)))

postnet.scm: USPS POSTNET Barcode Encoding in Scheme
prefix.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.1)
(require (planet "prefix.ss" ("jaymccarthy" "prefix.plt" 1 1)))

Tests students with regards to the use of prefix notation.
prophecy.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "prophecy.ss" ("dherman" "prophecy.plt" 1 0)))

A "future-generator" control construct, or "prophecy."
protobj.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "protobj.ss" ("neil" "protobj.plt" 1 0)))

Protobj: Prototype-Delegation Object Model in Scheme
roman.plt contributed by ams
documentationnbsp-nbsplatest version: 0.1nbsp-nbsplatest package version: (1.0)
(require (planet "roman.ss" ("ams" "roman.plt" 1 0)))

Utility functions for roman numerals.
scripting.plt contributed by ryanc
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "[file]" ("ryanc" "scripting.plt" 1 0)))

Scripting is a library of procedures useful for writing mzscheme scripts, especially those which execute external commands and manipulate the filesystem.
sqlid.plt contributed by oesterholtnbsp[library home page]
documentationnbsp-nbsplatest version: 1.01nbsp-nbsplatest package version: (1.2)
(require (planet "[file]" ("oesterholt" "sqlid.plt" 1 2)))

SQLI/SQLD is a framework for RDBM access.SQLD drivers are provided for SQLite3, PostgreSQL8, MySQL5, Oraclegt=8 and DB2gt=8
srfi.plt contributed by soegaard
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.1)
(require (planet "42.ss / 78.ss" ("soegaard" "srfi.plt" 1 1)))

SRFI Extensions and SRFI Drafts

SRFI 42 Eager comprehensions extended with the generators :match, :plt-match, :let-value, :pairs, :do-until, and more

SRFI 78 Draft Lightweight testing (pr 18-jan-2006)

syntax.plt contributed by soegaard
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "pp-syntax.scm" ("soegaard" "syntax.plt" 1 0)))

Pretty printing of expanded syntax. Provides unexpand and pp-syntax.
tabexpand.plt contributed by neilnbsp[library home page]
documentationnbsp-nbsplatest version: 0.2nbsp-nbsplatest package version: (1.0)
(require (planet "tabexpand.ss" ("neil" "tabexpand.plt" 1 0)))

tabexpand.scm: Tab Character Expansion in Scheme
tail.plt contributed by dherman
documentationnbsp-nbsplatest version: 1nbsp-nbsplatest package version: (1.0)
(require (planet "tail.ss" ("dherman" "tail.plt" 1 0)))

A special form for capturing a tail-context-preserving continuation.
with-bindings.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (1.2)
(require (planet "with-bindings.ss" ("jaymccarthy" "with-bindings.plt" 1 2)))

A convenient syntax for servlets.
xml-pull.plt contributed by dyoonbsp[library home page]
documentationnbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "xml-pull.ss" ("dyoo" "xml-pull.plt" 1 0)))

pull-style parsing for very large xml documents.
xxexpr.plt contributed by lshift
[no documentation available]nbsp-nbsplatest version: 1.0nbsp-nbsplatest package version: (1.0)
(require (planet "xxexpr.ss" ("lshift" "xxexpr.plt" 1 0)))

A library of writing functions for SXML.
yppdb.plt contributed by jaymccarthynbsp[library home page]
documentationnbsp-nbsplatest package version: (2.0)
(require (planet "yppdb.ss" ("jaymccarthy" "yppdb.plt" 2 0)))

Organizes your paper collection.

nbsp

diff --git a/collects/tests/mzscheme/benchmarks/mz/parsing.scm b/collects/tests/mzscheme/benchmarks/mz/parsing.scm new file mode 100644 index 0000000000..f91e9f9661 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/mz/parsing.scm @@ -0,0 +1,43 @@ +(require (lib "scheme-lexer.ss" "syntax-color")) + +(define path "~/proj/plt/collects/framework/private/frame.ss") + +(define content + (with-input-from-file path + (lambda () + (read-bytes (file-size path))))) + +(define e (make-object text%)) +(send e load-file path) + +(define (mk-p) + ;#; + (open-input-text-editor e) + #; + (open-input-bytes content) + #; + (open-input-string (send e get-text 0 'eof))) + +(let loop ([n 10]) + (unless (zero? n) + (printf "lexing~n") + (time + (let ([p (mk-p)]) + (port-count-lines! p) + (time + (let loop () + (let-values ([(a b c d e) (scheme-lexer p)]) + (unless (eq? 'eof b) + (loop))))))) + (printf "reading~n") + (time + (let ([p (mk-p)]) + (port-count-lines! p) + (time + (let loop () + (let ([v (read p)]) + (unless (eof-object? v) + (loop))))))) + (printf "done~n") + (loop (sub1 n)))) + diff --git a/collects/tests/mzscheme/benchmarks/mz/redsem.scm b/collects/tests/mzscheme/benchmarks/mz/redsem.scm new file mode 100644 index 0000000000..575f204b2d --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/mz/redsem.scm @@ -0,0 +1,6 @@ +(require (planet "beginner.ss" ("robby" "redex.plt") "examples")) +(collect-garbage) +(printf "Now\n") +(time (begin + (run-tests) (run-tests) (run-tests) (run-tests) (run-tests) + )) diff --git a/collects/tests/mzscheme/benchmarks/mz/ssax.scm b/collects/tests/mzscheme/benchmarks/mz/ssax.scm new file mode 100644 index 0000000000..1fa8254b7a --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/mz/ssax.scm @@ -0,0 +1,8 @@ +(require (planet "ssax.ss" ("lizorkin" "ssax.plt" 1 3))) + +(collect-garbage) +(time (void (ssax:xml->sxml + (open-input-file (build-path + (current-load-relative-directory) + "input.xml")) + null))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/README.txt b/collects/tests/mzscheme/benchmarks/shootout/README.txt new file mode 100644 index 0000000000..d09348bf09 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/README.txt @@ -0,0 +1,4 @@ +The program "run" should kknow how to run each benchmark with its +standard input value. So run like this: + + mzscheme -qu run.ss diff --git a/collects/tests/mzscheme/benchmarks/shootout/ackermann.ss b/collects/tests/mzscheme/benchmarks/shootout/ackermann.ss new file mode 100644 index 0000000000..1fc792dc7c --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/ackermann.ss @@ -0,0 +1,13 @@ +(module ackermann mzscheme + (define (ack m n) + (cond ((zero? m) (+ n 1)) + ((zero? n) (ack (- m 1) 1)) + (else (ack (- m 1) (ack m (- n 1)))))) + + (define (main args) + (let ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0))))) + (printf "Ack(3,~a): ~a~n" n (ack 3 n)))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/ary.ss b/collects/tests/mzscheme/benchmarks/shootout/ary.ss new file mode 100644 index 0000000000..26cead316f --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/ary.ss @@ -0,0 +1,21 @@ +(module ary mzscheme + (define (main args) + (let* ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0)))) + (x (make-vector n 0)) + (y (make-vector n 0)) + (last (- n 1))) + (do ((i 0 (+ i 1))) + ((= i n)) + (vector-set! x i (+ i 1))) + (do ((k 0 (+ k 1))) + ((= k 1000)) + (do ((i last (- i 1))) + ((< i 0)) + (vector-set! y i (+ (vector-ref x i) (vector-ref y i))))) + (print-list (vector-ref y 0) " " (vector-ref y last)))) + + (define (print-list . items) (for-each display items) (newline)) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/binarytrees.ss b/collects/tests/mzscheme/benchmarks/shootout/binarytrees.ss new file mode 100644 index 0000000000..f039b121b2 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/binarytrees.ss @@ -0,0 +1,45 @@ +;;; The Great Computer Language Shootout +;;; http://shootout.alioth.debian.org/ +;;; Derived from the Chicken variant by Sven Hartrumpf + +(module binarytrees mzscheme + + (define-struct node (left val right)) + (define-struct leaf (val)) + + (define (make item d) + (if (= d 0) + (make-leaf item) + (let ((item2 (* item 2)) + (d2 (- d 1))) + (make-node (make (- item2 1) d2) item (make item2 d2))))) + + (define (check t) + (if (leaf? t) + (leaf-val t) + (+ (node-val t) (- (check (node-left t)) (check (node-right t)))))) + + (define (main argv) + (let* ((min-depth 4) + (max-depth (max (+ min-depth 2) (string->number (vector-ref argv 0))))) + (let ((stretch-depth (+ max-depth 1))) + (printf "stretch tree of depth ~a\t check: ~a\n" + stretch-depth + (check (make 0 stretch-depth)))) + (let ((long-lived-tree (make 0 max-depth))) + (do ((d 4 (+ d 2)) + (c 0 0)) + ((> d max-depth)) + (let ((iterations (arithmetic-shift 1 (+ (- max-depth d) min-depth)))) + (do ((i 0 (+ i 1))) + ((>= i iterations)) + (set! c (+ c (check (make i d)) (check (make (- i) d))))) + (printf "~a\t trees of depth ~a\t check: ~a\n" + (* 2 iterations) + d + c))) + (printf "long lived tree of depth ~a\t check: ~a\n" + max-depth + (check long-lived-tree))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/chameneos.ss b/collects/tests/mzscheme/benchmarks/shootout/chameneos.ss new file mode 100644 index 0000000000..b98a239c36 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/chameneos.ss @@ -0,0 +1,55 @@ +;;; The Great Computer Language Shootout +;;; http://shootout.alioth.debian.org/ + +(module chameneos mzscheme + + (define (change c1 c2) + (case c1 + [(red) + (case c2 [(blue) 'yellow] [(yellow) 'blue] [else c1])] + [(yellow) + (case c2 [(blue) 'red] [(red) 'blue] [else c1])] + [(blue) + (case c2 [(yellow) 'red] [(red) 'yellow] [else c1])])) + + (define (place meeting-ch n) + (thread + (lambda () + (let loop ([n n]) + (if (zero? n) + ;; Fade all: + (let loop () + (let ([c (channel-get meeting-ch)]) + (channel-put (car c) #f) + (loop))) + ;; Let two meet: + (let ([c1 (channel-get meeting-ch)] + [c2 (channel-get meeting-ch)]) + (channel-put (car c1) (cdr c2)) + (channel-put (car c2) (cdr c1)) + (loop (sub1 n)))))))) + + (define (creature color meeting-ch result-ch) + (thread + (lambda () + (let ([ch (make-channel)]) + (let loop ([color color][met 0]) + (channel-put meeting-ch (cons ch color)) + (let ([other-color (channel-get ch)]) + (if other-color + ;; Meet: + (loop (change color other-color) (add1 met)) + ;; Done: + (channel-put result-ch met)))))))) + + (let ([result-ch (make-channel)] + [meeting-ch (make-channel)]) + (place meeting-ch (string->number (vector-ref (current-command-line-arguments) 0))) + (creature 'blue meeting-ch result-ch) + (creature 'red meeting-ch result-ch) + (creature 'yellow meeting-ch result-ch) + (creature 'blue meeting-ch result-ch) + (printf "~a\n" (+ (channel-get result-ch) + (channel-get result-ch) + (channel-get result-ch) + (channel-get result-ch))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/cheapconcurrency.ss b/collects/tests/mzscheme/benchmarks/shootout/cheapconcurrency.ss new file mode 100644 index 0000000000..ea035a9298 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/cheapconcurrency.ss @@ -0,0 +1,24 @@ + +(module cheapconcurrency mzscheme + + (define (generate receive-ch n) + (if (zero? n) + receive-ch + (let ([ch (make-channel)]) + (thread (lambda () + (let loop () + (channel-put ch (add1 (channel-get receive-ch))) + (loop)))) + (generate ch (sub1 n))))) + + (let ([n (string->number + (vector-ref (current-command-line-arguments) 0))]) + (let* ([start-ch (make-channel)] + [end-ch (generate start-ch 500)]) + (let loop ([n n][total 0]) + (if (zero? n) + (printf "~a\n" total) + (begin + (channel-put start-ch 0) + (loop (sub1 n) + (+ total (channel-get end-ch))))))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/echo.ss b/collects/tests/mzscheme/benchmarks/shootout/echo.ss new file mode 100644 index 0000000000..bf338237ee --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/echo.ss @@ -0,0 +1,45 @@ +(module echo mzscheme + (define PORT 8888) + (define DATA "Hello there sailor\n") + (define n 10) + + (define (server) + (thread client) + (let-values ([(in out) (tcp-accept (tcp-listen PORT 5 #t))] + [(buffer) (make-string (string-length DATA))]) + (file-stream-buffer-mode out 'none) + (let loop ([i (read-string! buffer in)] + [bytes 0]) + (if (not (eof-object? i)) + (begin + (display buffer out) + (loop (read-string! buffer in) + (+ bytes (string-length buffer)))) + (begin + (display "server processed ") + (display bytes) + (display " bytes\n")))))) + + (define (client) + (let-values ([(in out) (tcp-connect "127.0.0.1" PORT)] + [(buffer) (make-string (string-length DATA))]) + (file-stream-buffer-mode out 'none) + (let loop ([n n]) + (if (> n 0) + (begin + (display DATA out) + (let ([i (read-string! buffer in)]) + (begin + (if (equal? DATA buffer) + (loop (- n 1)) + 'error)))) + (close-output-port out))))) + + (define (main args) + (set! n + (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0)))) + (server)) + + (main (current-command-line-arguments))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/except.ss b/collects/tests/mzscheme/benchmarks/shootout/except.ss new file mode 100644 index 0000000000..cffbb7d7a2 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/except.ss @@ -0,0 +1,36 @@ +(module except mzscheme + (define HI 0) + (define LO 0) + + (define (hi-excp? x) (eq? x 'Hi_Exception)) + (define (lo-excp? x) (eq? x 'Lo_Exception)) + (define (true? x) (if (boolean? x) x #t)) + + (define (some_fun n) + (with-handlers + ([true? (lambda (exn) #f)]) + (hi_fun n))) + + (define (hi_fun n) + (with-handlers + ([hi-excp? (lambda (exn) (set! HI (+ HI 1))) ]) + (lo_fun n))) + + (define (lo_fun n) + (with-handlers + ([lo-excp? (lambda (exn) (set! LO (+ LO 1))) ]) + (blowup n))) + + (define (blowup n) + (if (= 0 (modulo n 2)) + (raise 'Hi_Exception) + (raise 'Lo_Exception))) + + (define (main args) + (let* ((n (if (= (vector-length args) 1) (string->number (vector-ref args 0)) 1))) + (do ((i 0 (+ i 1))) + ((= i n)) + (some_fun i))) + (printf "Exceptions: HI=~a / LO=~a~n" HI LO)) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/fannkuch.ss b/collects/tests/mzscheme/benchmarks/shootout/fannkuch.ss new file mode 100644 index 0000000000..f9a80228d0 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/fannkuch.ss @@ -0,0 +1,86 @@ +#!/usr/bin/mzscheme -qu +;; fannkuch benchmark for The Computer Language Shootout +;; Written by Dima Dorfman, 2004 +;; Slightly improved by Sven Hartrumpf, 2005-2006 +;; +;; Ever-so-slightly tweaked for MzScheme by Brent Fulgham + +(module fannkuch mzscheme + (define vector-for-each (lambda (pred v) + (do ((i 0 (add1 i)) + (v-length (vector-length v))) + ((>= i v-length)) + (pred (vector-ref v i))))) + + (define (vector-reverse-slice! v i j) + (do ((i i (add1 i)) + (j (sub1 j) (sub1 j))) ; exclude position j + ((<= j i)) + (vector-swap! v i j))) + + (define (vector-swap! v i j) + (let ((t (vector-ref v i))) + (vector-set! v i (vector-ref v j)) + (vector-set! v j t))) + + (define (count-flips pi) + (do ((rho (vector-copy pi)) + (i 0 (add1 i))) + ((= (vector-ref rho 0) 0) i) + (vector-reverse-slice! rho 0 (add1 (vector-ref rho 0))))) + + (define (vector-copy source) + (do ((vec (make-vector (vector-length source))) + (i 0 (add1 i))) + ((= i (vector-length source)) vec) + (vector-set! vec i (vector-ref source i)))) + + (define (fannkuch n) + (let ((pi (do ((pi (make-vector n)) + (i 0 (add1 i))) + ((= i n) pi) + (vector-set! pi i i))) + (r n) + (count (make-vector n))) + (let loop ((flips 0) + (perms 0)) + (cond ((< perms 30) + (vector-for-each (lambda (x) + (display (add1 x))) + pi) + (newline))) + (do () + ((= r 1)) + (vector-set! count (sub1 r) r) + (set! r (sub1 r))) + (let ((flips2 (max (count-flips pi) flips))) + (let ((result + (let loop2 () + (if (= r n) + flips2 + (let ((perm0 (vector-ref pi 0))) + (do ((i 0)) + ((>= i r)) + (let ((j (add1 i))) + (vector-set! pi i (vector-ref pi j)) + (set! i j))) + (vector-set! pi r perm0) + (vector-set! count r (sub1 (vector-ref count r))) + (cond ((<= (vector-ref count r) 0) + (set! r (add1 r)) + (loop2)) + (else + #f))))))) + (or result + (loop flips2 (add1 perms))) + ))))) + + (define (main args) + (if (< (vector-length args) 1) + (begin (display "An argument is required") (newline) 2) + (let ((n (string->number (vector-ref args 0)))) + (if (not (integer? n)) + (begin (display "An integer is required") (newline) 2) + (printf "Pfannkuchen(~S) = ~S~%" n (fannkuch n)))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/fasta.ss b/collects/tests/mzscheme/benchmarks/shootout/fasta.ss new file mode 100644 index 0000000000..f1a04322f1 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/fasta.ss @@ -0,0 +1,119 @@ +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; fasta - benchmark +;; +;; Derived from the Chicken variant, which was +;; Contributed by Anthony Borla + +(module fasta mzscheme + + (define +alu+ + (bytes-append + #"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + #"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + #"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + #"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + #"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + #"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + #"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA")) + + (define +iub+ + (list + '(#\a . 0.27) '(#\c . 0.12) '(#\g . 0.12) '(#\t . 0.27) '(#\B . 0.02) + '(#\D . 0.02) '(#\H . 0.02) '(#\K . 0.02) '(#\M . 0.02) '(#\N . 0.02) + '(#\R . 0.02) '(#\S . 0.02) '(#\V . 0.02) '(#\W . 0.02) '(#\Y . 0.02))) + + (define +homosapien+ + (list + '(#\a . 0.3029549426680) '(#\c . 0.1979883004921) + '(#\g . 0.1975473066391) '(#\t . 0.3015094502008))) + + ;; ------------- + + (define +line-size+ 60) + + ;; ------------------------------- + + (define (make-random seed) + (let* ((ia 3877) (ic 29573) (im 139968) (last seed)) + (lambda (max) + (set! last (modulo (+ ic (* last ia)) im)) + (/ (* max last) im) ))) + + ;; ------------------------------- + + (define (make-cumulative-table frequency-table) + (let ((cumulative 0.0)) + (map + (lambda (x) + (set! cumulative (+ cumulative (cdr x))) + (cons (char->integer (car x)) cumulative)) + frequency-table))) + + ;; ------------- + + (define random-next (make-random 42)) + (define +segmarker+ ">") + + ;; ------------- + + (define (select-random cumulative-table) + (let ((rvalue (random-next 1.0))) + (select-over-threshold rvalue cumulative-table))) + + (define (select-over-threshold rvalue table) + (if (<= rvalue (cdar table)) + (caar table) + (select-over-threshold rvalue (cdr table)))) + + ;; ------------- + + (define (repeat-fasta id desc n_ sequence line-length) + (let ((seqlen (bytes-length sequence)) + (out (current-output-port))) + (display (string-append +segmarker+ id " " desc "\n") out) + (let loop-o ((n n_) (k 0)) + (unless (<= n 0) + (let ((m (min n line-length))) + (let loop-i ((i 0) (k k)) + (if (>= i m) + (begin + (newline out) + (loop-o (- n line-length) k)) + (let ([k (if (= k seqlen) 0 k)]) + (write-byte (bytes-ref sequence k) out) + (loop-i (add1 i) (add1 k)))))))))) + + ;; ------------- + + (define (random-fasta id desc n_ cumulative-table line-length) + (let ((out (current-output-port))) + (display (string-append +segmarker+ id " " desc "\n") out) + (let loop-o ((n n_)) + (unless (<= n 0) + (let ((m (min n line-length))) + (let loop-i ((i 0)) + (unless (>= i m) + (write-byte (select-random cumulative-table) out) + (loop-i (add1 i)))) + (newline out) + (loop-o (- n line-length))))))) + + ;; ------------------------------- + + (define (main args) + (let ((n (string->number (vector-ref args 0)))) + + (repeat-fasta "ONE" "Homo sapiens alu" (* n 2) +alu+ +line-size+) + + (random-fasta "TWO" "IUB ambiguity codes" (* n 3) + (make-cumulative-table +iub+) +line-size+) + + (random-fasta "THREE" "Homo sapiens frequency" (* n 5) + (make-cumulative-table +homosapien+) +line-size+) )) + + ;; ------------------------------- + + (main (current-command-line-arguments))) + diff --git a/collects/tests/mzscheme/benchmarks/shootout/fibo.ss b/collects/tests/mzscheme/benchmarks/shootout/fibo.ss new file mode 100644 index 0000000000..f538eba096 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/fibo.ss @@ -0,0 +1,13 @@ +(module fibo mzscheme + (define (fib n) + (cond ((< n 2) 1) + (else (+ (fib (- n 2)) (fib (- n 1)))))) + + (define (main args) + (let ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0))))) + (display (fib n)) + (newline))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/hash.ss b/collects/tests/mzscheme/benchmarks/shootout/hash.ss new file mode 100644 index 0000000000..f03cecc2a8 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/hash.ss @@ -0,0 +1,18 @@ +(module hash mzscheme + (define (main argv) + (let* ([n (string->number (vector-ref argv 0))] + [hash (make-hash-table 'equal)] + [accum 0] + [false (lambda () #f)]) + (let loop ([i 1]) + (unless (> i n) + (hash-table-put! hash (number->string i 16) i) + (loop (add1 i)))) + (let loop ([i n]) + (unless (zero? i) + (when (hash-table-get hash (number->string i) false) + (set! accum (+ accum 1))) + (loop (sub1 i)))) + (printf "~s~n" accum))) + + (main (current-command-line-arguments))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/hash2.ss b/collects/tests/mzscheme/benchmarks/shootout/hash2.ss new file mode 100644 index 0000000000..858787e0b9 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/hash2.ss @@ -0,0 +1,25 @@ +(module hash2 mzscheme + (define (main argv) + (let* ([n (string->number (vector-ref argv 0))] + [hash1 (make-hash-table 'equal)] + [hash2 (make-hash-table 'equal)] + [zero (lambda () 0)]) + (let loop ([i 0]) + (unless (= i 10000) + (hash-table-put! hash1 (string-append "foo_" (number->string i)) i) + (loop (add1 i)))) + (let loop ([i 0]) + (unless (= i n) + (hash-table-for-each hash1 (lambda (key value) + (hash-table-put! + hash2 + key + (+ (hash-table-get hash2 key zero) value)))) + (loop (add1 i)))) + (printf "~s ~s ~s ~s~n" + (hash-table-get hash1 "foo_1") + (hash-table-get hash1 "foo_9999") + (hash-table-get hash2 "foo_1") + (hash-table-get hash2 "foo_9999")))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/heapsort.ss b/collects/tests/mzscheme/benchmarks/shootout/heapsort.ss new file mode 100644 index 0000000000..6e06323155 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/heapsort.ss @@ -0,0 +1,74 @@ +;;; heapsort.scm + +;; Prints 0.9990640717878372 instead of 0.9990640718 when n=1000. +;; Updated by Justin Smith +;; +;; Updated by Brent Fulgham to provide proper output formatting + +(module heapsort mzscheme + (require (only (lib "13.ss" "srfi") string-index string-pad-right)) + + (define IM 139968) + (define IA 3877) + (define IC 29573) + + (define LAST 42) + (define (gen_random max) + (set! LAST (modulo (+ (* LAST IA) IC) IM)) + (/ (* max LAST) IM)) + + (define (heapsort n ra) + (let ((ir n) + (l (+ (quotient n 2) 1)) + (i 0) + (j 0) + (rra 0.0)) + (let/ec return + (do ((bar #t)) + ((= 1 0)) + (cond ((> l 1) + (set! l (- l 1)) + (set! rra (vector-ref ra l))) + (else + (set! rra (vector-ref ra ir)) + (vector-set! ra ir (vector-ref ra 1)) + (set! ir (- ir 1)) + (cond ((<= ir 1) + (vector-set! ra 1 rra) + (return #t))))) + (set! i l) + (set! j (* l 2)) + (do ((foo #t)) + ((> j ir)) + (cond ((and (< j ir) (< (vector-ref ra j) (vector-ref ra (+ j 1)))) + (set! j (+ j 1)))) + (cond ((< rra (vector-ref ra j)) + (vector-set! ra i (vector-ref ra j)) + (set! i j) + (set! j (+ j i))) + (else + (set! j (+ ir 1))))) + (vector-set! ra i rra))))) + + (define (roundto digits num) + (let* ([e (expt 10 digits)] + [num (round (* e (inexact->exact num)))]) + (format "~a.~a" + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + (define (main args) + (let* ((n (or (and (= (vector-length args) 1) (string->number (vector-ref args 0))) + 1)) + (last (+ n 1)) + (ary (make-vector last 0))) + (do ((i 1 (+ i 1))) + ((= i last)) + (vector-set! ary i (gen_random 1.0))) + (heapsort n ary) + (printf "~a~n" + (roundto 10 (vector-ref ary n))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/lists.ss b/collects/tests/mzscheme/benchmarks/shootout/lists.ss new file mode 100644 index 0000000000..17a0b9a4fa --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/lists.ss @@ -0,0 +1,43 @@ +(module lists mzscheme + (define SIZE 10000) + + (define (sequence start stop) + (if (> start stop) + '() + (cons start (sequence (+ start 1) stop)))) + + (define (head-to-tail! headlist taillist) + (when (null? taillist) (begin + (set! taillist (list (car headlist))) + (set! headlist (cdr headlist)))) + (letrec ((htt-helper (lambda (dest) + (when (not (null? headlist)) + (let ((headlink headlist)) + (set-cdr! dest headlink) + (set! headlist (cdr headlist)) + (htt-helper headlink)))))) + (htt-helper taillist) + (values headlist taillist))) + + (define (test-lists) + (let* ([L1 (sequence 1 SIZE)] + [L2 (append L1 '())] + [L3 '()]) + (set!-values (L2 L3) (head-to-tail! L2 L3)) + (set!-values (L3 L2) (head-to-tail! (reverse! L3) L2)) + (set! L1 (reverse! L1)) + (cond ((not (= SIZE (car L1))) 0) + ((not (equal? L1 L2)) 0) + (else (length L1))))) + + (define (main args) + (let ((result #f)) + (let loop ((counter (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0))))) + (when (> counter 0) + (set! result (test-lists)) + (loop (- counter 1)))) + (printf "~s~n" result))) + + (main (current-command-line-arguments))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss new file mode 100644 index 0000000000..b12521f837 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss @@ -0,0 +1,80 @@ +;; --------------------------------------------------------------------- +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Derived from the Chicken variant, which was +;; Contributed by Anthony Borla + +;; Note: as of version 350, this benchmark spends much of +;; its time GCing; it runs 2 times as fast in mzscheme3m. + +;; The version that uses complex number is a little +;; more elegant, but slower: +;; (define (mandelbrot iterations x y n ci) +;; (let ((c (+ (- (/ (* 2.0 x) n) 1.5) +;; (* ci 0.0+1.0i)))) +;; (let loop ((i 0) (z 0.0+0.0i)) +;; (cond +;; [(> i iterations) 1] +;; [(> (magnitude z) 2.0) 0] +;; [else (loop (add1 i) (+ (* z z) c))])))) + + +(module mandelbrot mzscheme + + ;; ------------------------------- + + (define +limit-sqr+ 4.0) + + (define +iterations+ 50) + + ;; ------------------------------- + + (define (mandelbrot iterations x y n ci) + (let ((cr (- (/ (* 2.0 x) n) 1.5))) + (let loop ((i 0) (zr 0.0) (zi 0.0)) + (if (> i iterations) + 1 + (let ((zrq (* zr zr)) + (ziq (* zi zi))) + (cond + ((> (+ zrq ziq) +limit-sqr+) 0) + (else (loop (add1 i) (+ (- zrq ziq) cr) (+ (* 2.0 zr zi) ci))))))))) + + ;; ------------------------------- + + (define (main args) + (let ((n (string->number (vector-ref args 0))) + (out (current-output-port))) + + (fprintf out "P4\n~a ~a\n" n n) + + (let loop-y ((y 0)) + + (when (< y n) + + (let ([ci (- (/ (* 2.0 y) n) 1.0)]) + + (let loop-x ((x 0) (bitnum 0) (byteacc 0)) + + (if (< x n) + (let ([bitnum (add1 bitnum)] + [byteacc (+ (arithmetic-shift byteacc 1) + (mandelbrot +iterations+ x y n ci))]) + + (cond + ((= bitnum 8) + (write-byte byteacc out) + (loop-x (add1 x) 0 0)) + + [else (loop-x (add1 x) bitnum byteacc)])) + + (begin + (when (positive? bitnum) + (write-byte (arithmetic-shift byteacc (- 8 (bitwise-and n #x7))) out)) + + (loop-y (add1 y)))))))))) + + ;; ------------------------------- + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/matrix.ss b/collects/tests/mzscheme/benchmarks/shootout/matrix.ss new file mode 100644 index 0000000000..534fe27d76 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/matrix.ss @@ -0,0 +1,76 @@ +; Matrix.scm + +(module matrix mzscheme + (define size 30) + + (define (1+ x) (+ x 1)) + + (define (mkmatrix rows cols) + (let ((mx (make-vector rows 0)) + (count 1)) + (do ((i 0 (1+ i))) + ((= i rows)) + (let ((row (make-vector cols 0))) + (do ((j 0 (1+ j))) + ((= j cols)) + (vector-set! row j count) + (set! count (+ count 1))) + (vector-set! mx i row))) + mx)) + + (define (num-cols mx) + (let ((row (vector-ref mx 0))) + (vector-length row))) + + (define (num-rows mx) + (vector-length mx)) + + (define (mmult rows cols m1 m2) + (let ((m3 (make-vector rows 0))) + (do ((i 0 (1+ i))) + ((= i rows)) + (let ((m1i (vector-ref m1 i)) + (row (make-vector cols 0))) + (do ((j 0 (1+ j))) + ((= j cols)) + (let ((val 0)) + (do ((k 0 (1+ k))) + ((= k cols)) + (set! val (+ val (* (vector-ref m1i k) + (vector-ref (vector-ref m2 k) j))))) + (vector-set! row j val))) + (vector-set! m3 i row))) + m3)) + + (define (matrix-print m) + (do ((i 0 (1+ i))) + ((= i (num-rows m))) + (let ((row (vector-ref m i))) + (do ((j 0 (1+ j))) + ((= j (num-cols m))) + (display (vector-ref row j)) + (if (< j (num-cols m)) + (display " "))) + (newline)))) + + (define (print-list . items) (for-each display items) (newline)) + + (define (main args) + (let ((n (or (and (= (vector-length args) 1) (string->number (vector-ref + args 0))) + 1))) + (let ((mm 0) + (m1 (mkmatrix size size)) + (m2 (mkmatrix size size))) + (let loop ((iter n)) + (cond ((> iter 0) + (set! mm (mmult size size m1 m2)) + (loop (- iter 1))))) + (let ((r0 (vector-ref mm 0)) + (r2 (vector-ref mm 2)) + (r3 (vector-ref mm 3)) + (r4 (vector-ref mm 4))) + (print-list (vector-ref r0 0) " " (vector-ref r2 3) " " + (vector-ref r3 2) " " (vector-ref r4 4)))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/moments.ss b/collects/tests/mzscheme/benchmarks/shootout/moments.ss new file mode 100644 index 0000000000..f7860380f4 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/moments.ss @@ -0,0 +1,72 @@ +; Moments.scm + +(module moments mzscheme + (require (only (lib "list.ss") sort)) + + (define (roundto digits n) + (let* ([e (expt 10 digits)] + [num (round (abs (* e (inexact->exact n))))]) + (format "~a~a.~a" + (if (negative? n) "-" "") + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + (let* ((sum 0.0) + (numlist (let loop ((line (read-line)) (numlist '())) + (cond ((eof-object? line) numlist) + (else + (let ((num (string->number line))) + (set! sum (+ num sum)) + (loop (read-line) (cons num numlist)))))))) + (let ((n (length numlist))) + (let ((mean (/ sum n)) + (average_deviation 0.0) + (standard_deviation 0.0) + (variance 0.0) + (skew 0.0) + (kurtosis 0.0) + (median 0.0) + (deviation 0.0)) + (let loop ((nums numlist)) + (if (not (null? nums)) + (begin + (set! deviation (- (car nums) mean)) + (set! average_deviation (+ average_deviation (abs deviation))) + (set! variance (+ variance (expt deviation 2.0))) + (set! skew (+ skew (expt deviation 3.0))) + (set! kurtosis (+ kurtosis (expt deviation 4))) + (loop (cdr nums))))) + + (set! average_deviation (/ average_deviation (exact->inexact n))) + (set! variance (/ variance (- n 1))) + (set! standard_deviation (sqrt variance)) + + (cond ((> variance 0.0) + (set! skew (/ skew (* n variance standard_deviation))) + (set! kurtosis (- (/ kurtosis (* n variance variance)) + 3.0)))) + + (set! numlist (sort numlist (lambda (x y) (< x y)))) + + (let ((mid (quotient n 2))) + (if (zero? (modulo n 2)) + (set! median (/ (+ (car (list-tail numlist mid)) + (car (list-tail numlist (- mid 1)))) + 2.0)) + (set! median (car (list-tail numlist mid))))) + + + (set! standard_deviation (/ (round (* standard_deviation 1000000)) + 1000000)) + + (for-each display + `("n: " ,n "\n" + "median: " ,(roundto 6 median) "\n" + "mean: " ,(roundto 6 mean) "\n" + "average_deviation: " ,(roundto 6 average_deviation ) "\n" + "standard_deviation: " ,(roundto 6 standard_deviation) "\n" + "variance: " ,(roundto 6 variance)"\n" + "skew: " ,(roundto 6 skew) "\n" + "kurtosis: " ,(roundto 6 kurtosis)"\n" )))))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/nbody.ss b/collects/tests/mzscheme/benchmarks/shootout/nbody.ss new file mode 100644 index 0000000000..1dd9802e12 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/nbody.ss @@ -0,0 +1,166 @@ +#!/usr/bin/mzscheme -qu +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Imperative-style implementation based on the SBCL implementation by +;; Patrick Frankenberger and Juho Snellman, but using only native Scheme +;; idioms like 'named let' and 'do' special form. +;; +;; Contributed by Anthony Borla, then converted for mzscheme +;; by Matthew Flatt and Brent Fulgham + +#| +Correct output N = 1000 is + +-0.169075164 +-0.169087605 +|# +(module nbody mzscheme + (provide main) + + ;;; Stupid boiler-plate for formatting floating point value + (define (roundto digits n) + (let* ([e (expt 10 digits)] + [num (round (abs (* e (inexact->exact n))))]) + (format "~a~a.~a" + (if (negative? n) "-" "") + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + ;; ------------------------------ + ;; define planetary masses, initial positions & velocity + + (define +pi+ 3.141592653589793) + (define +days-per-year+ 365.24) + + (define +solar-mass+ (* 4 +pi+ +pi+)) + + (define-struct body (x y z vx vy vz mass)) + + (define *sun* + (make-body 0.0 0.0 0.0 0.0 0.0 0.0 +solar-mass+)) + + (define *jupiter* + (make-body 4.84143144246472090 + -1.16032004402742839 + -1.03622044471123109e-1 + (* 1.66007664274403694e-3 +days-per-year+) + (* 7.69901118419740425e-3 +days-per-year+) + (* -6.90460016972063023e-5 +days-per-year+) + (* 9.54791938424326609e-4 +solar-mass+))) + + (define *saturn* + (make-body 8.34336671824457987 + 4.12479856412430479 + -4.03523417114321381e-1 + (* -2.76742510726862411e-3 +days-per-year+) + (* 4.99852801234917238e-3 +days-per-year+) + (* 2.30417297573763929e-5 +days-per-year+) + (* 2.85885980666130812e-4 +solar-mass+))) + + (define *uranus* + (make-body 1.28943695621391310e1 + -1.51111514016986312e1 + -2.23307578892655734e-1 + (* 2.96460137564761618e-03 +days-per-year+) + (* 2.37847173959480950e-03 +days-per-year+) + (* -2.96589568540237556e-05 +days-per-year+) + (* 4.36624404335156298e-05 +solar-mass+))) + + (define *neptune* + (make-body 1.53796971148509165e+01 + -2.59193146099879641e+01 + 1.79258772950371181e-01 + (* 2.68067772490389322e-03 +days-per-year+) + (* 1.62824170038242295e-03 +days-per-year+) + (* -9.51592254519715870e-05 +days-per-year+) + (* 5.15138902046611451e-05 +solar-mass+))) + + ;; ------------------------------- + (define (offset-momentum system) + (let loop-i ((i system) (px 0.0) (py 0.0) (pz 0.0)) + (if (null? i) + (begin + (set-body-vx! (car system) (/ (- px) +solar-mass+)) + (set-body-vy! (car system) (/ (- py) +solar-mass+)) + (set-body-vz! (car system) (/ (- pz) +solar-mass+))) + (loop-i (cdr i) + (+ px (* (body-vx (car i)) (body-mass (car i)))) + (+ py (* (body-vy (car i)) (body-mass (car i)))) + (+ pz (* (body-vz (car i)) (body-mass (car i)))))))) + + ;; ------------------------------- + (define (energy system) + (let loop-o ((o system) (e 0.0)) + (if (null? o) + e + (let ([e (+ e (* 0.5 (body-mass (car o)) + (+ (* (body-vx (car o)) (body-vx (car o))) + (* (body-vy (car o)) (body-vy (car o))) + (* (body-vz (car o)) (body-vz (car o))))))]) + + (let loop-i ((i (cdr o)) (e e)) + (if (null? i) + (loop-o (cdr o) e) + (let* ((dx (- (body-x (car o)) (body-x (car i)))) + (dy (- (body-y (car o)) (body-y (car i)))) + (dz (- (body-z (car o)) (body-z (car i)))) + (distance (sqrt (+ (* dx dx) (* dy dy) (* dz dz))))) + (let ([e (- e (/ (* (body-mass (car o)) (body-mass (car i))) distance))]) + (loop-i (cdr i) e))))))))) + + ;; ------------------------------- + (define (advance system dt) + (let loop-o ((o system)) + (unless (null? o) + (let loop-i ((i (cdr o))) + (unless (null? i) + (let* ((o1 (car o)) + (i1 (car i)) + (dx (- (body-x o1) (body-x i1))) + (dy (- (body-y o1) (body-y i1))) + (dz (- (body-z o1) (body-z i1))) + (distance (sqrt (+ (* dx dx) (* dy dy) (* dz dz)))) + (mag (/ dt (* distance distance distance))) + (dxmag (* dx mag)) + (dymag (* dy mag)) + (dzmag (* dz mag)) + (om (body-mass o1)) + (im (body-mass i1))) + (set-body-vx! o1 (- (body-vx o1) (* dxmag im))) + (set-body-vy! o1 (- (body-vy o1) (* dymag im))) + (set-body-vz! o1 (- (body-vz o1) (* dzmag im))) + (set-body-vx! i1 (+ (body-vx i1) (* dxmag om))) + (set-body-vy! i1 (+ (body-vy i1) (* dymag om))) + (set-body-vz! i1 (+ (body-vz i1) (* dzmag om))) + (loop-i (cdr i))))) + (loop-o (cdr o)))) + + (let loop-o ((o system)) + (unless (null? o) + (let ([o1 (car o)]) + (set-body-x! o1 (+ (body-x o1) (* dt (body-vx o1)))) + (set-body-y! o1 (+ (body-y o1) (* dt (body-vy o1)))) + (set-body-z! o1 (+ (body-z o1) (* dt (body-vz o1)))) + (loop-o (cdr o)))))) + + ;; ------------------------------- + (define (main args) + (let ((n (if (null? args) + 1 + (string->number (car args)))) + (system (list *sun* *jupiter* *saturn* *uranus* *neptune*))) + + (offset-momentum system) + + (printf "~a~%" (roundto 9 (energy system))) + + (do ((i 1 (+ i 1))) + ((< n i)) + (advance system 0.01)) + + (printf "~a~%" (roundto 9 (energy system))))) + + (main (vector->list (current-command-line-arguments)))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nestedloop.ss b/collects/tests/mzscheme/benchmarks/shootout/nestedloop.ss new file mode 100644 index 0000000000..e972c5911a --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/nestedloop.ss @@ -0,0 +1,18 @@ +(module nestedloop mzscheme + (require (lib "defmacro.ss")) + + (define-macro (nest n expr) + (if (> n 0) + `(let loop ([i 1]) (unless (> i n) + (nest ,(- n 1) ,expr) + (loop (add1 i)))) + expr)) + + + (define (main argv) + (let* ([n (string->number (vector-ref argv 0))] + [x 0]) + (nest 6 (set! x (+ x 1))) + (printf "~s~n" x))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nsieve.ss b/collects/tests/mzscheme/benchmarks/shootout/nsieve.ss new file mode 100644 index 0000000000..1386c675d6 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/nsieve.ss @@ -0,0 +1,50 @@ +#!/usr/bin/mzscheme -qu +;; $Id: nsieve-mzscheme.code,v 1.6 2006/06/10 23:38:29 bfulgham Exp $ +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; nsieve benchmark for The Computer Language Shootout +;; Written by Dima Dorfman, 2004 +;; Converted to MzScheme by Brent Fulgham + +(module nseive mzscheme + (require (only (lib "13.ss" "srfi") string-index string-pad)) + + (define (nsieve m) + (let ((a (make-vector m #t))) + (let loop ((i 2) (n 0)) + (if (< i m) + (begin + (if (vector-ref a i) + (begin + (let clear ((j (+ i i))) + (if (< j m) + (begin + (vector-set! a j #f) + (clear (+ j i))))) + (loop (+ 1 i) (+ 1 n))) + (loop (+ 1 i) n))) + n)))) + + (define (test n) + (let* ((m (* (expt 2 n) 10000)) + (count (nsieve m))) + (printf "Primes up to ~a ~a~%" + (string-pad (number->string m) 8) + (string-pad (number->string count) 8)))) + + (define (main args) + (if (< (vector-length args) 1) + (begin + (display "An argument is required") (newline) 2) + (let ((n (string->number (vector-ref args 0)))) + (if (not n) + (begin + (display "An integer is required") (newline) 2) + (begin + (if (>= n 0) (test n)) + (if (>= n 1) (test (- n 1))) + (if (>= n 2) (test (- n 2))) + 0))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nsievebits.ss b/collects/tests/mzscheme/benchmarks/shootout/nsievebits.ss new file mode 100644 index 0000000000..806a79b65a --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/nsievebits.ss @@ -0,0 +1,66 @@ +#!/usr/bin/mzscheme -qu +;;; The Great Computer Language Shootout +;;; http://shootout.alioth.debian.org/ +;; +;; Adapted from CMUCL code by Dima Dorfman; bit-vector stuff by Alex Shinn; +;; cobbled together by felix, converted to MzScheme by Brent Fulgham +;; Note: Requires MzScheme 299+ + +(module nsievebits mzscheme + + (define (make-bit-vector size) + (let* ((len (quotient (+ size 7) 8)) + (res (make-bytes len #b11111111))) + (let ((off (remainder size 8))) + (unless (zero? off) + (bytes-set! res (- len 1) (- (arithmetic-shift 1 off) 1)))) + res)) + + (define (bit-vector-ref vec i) + (let ((byte (arithmetic-shift i -3)) + (off (bitwise-and i #x7))) + (and (< byte (bytes-length vec)) + (not (zero? (bitwise-and (bytes-ref vec byte) + (arithmetic-shift 1 off))))))) + + (define (bit-vector-set! vec i x) + (let ((byte (arithmetic-shift i -3)) + (off (bitwise-and i #x7))) + (let ((val (bytes-ref vec byte)) + (mask (arithmetic-shift 1 off))) + (bytes-set! vec + byte + (if x + (bitwise-ior val mask) + (bitwise-and val (bitwise-not mask))))))) + + (define (nsievebits m) + (let ((a (make-bit-vector m))) + (define (clear i) + (do ([j (+ i i) (+ j i)]) + ((>= j m)) + (bit-vector-set! a j #f) ) ) + (let ([c 0]) + (do ([i 2 (add1 i)]) + ((>= i m) c) + (when (bit-vector-ref a i) + (clear i) + (set! c (add1 c)) ) ) ) ) ) + + (define (string-pad s n) + (string-append (make-string (- n (string-length s)) #\space) + s)) + + (define (test n) + (let ((m (* 10000 (arithmetic-shift 1 n)))) + (printf "Primes up to ~a ~a~%" + (string-pad (number->string m) 8) + (string-pad (number->string (nsievebits m)) 8)))) + + (define (main args) + (let ([n (string->number (vector-ref args 0))]) + (when (>= n 0) (test n)) + (when (>= n 1) (test (- n 1))) + (when (>= n 2) (test (- n 2))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/partialsums.ss b/collects/tests/mzscheme/benchmarks/shootout/partialsums.ss new file mode 100644 index 0000000000..56db6e6b9c --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/partialsums.ss @@ -0,0 +1,70 @@ +;; --------------------------------------------------------------------- +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Based on D language implementation by Dave Fladebo [imperative version] +;; +;; Derived from the Chicken variant, which was +;; Contributed by Anthony Borla +;; --------------------------------------------------------------------- + +;; Note: as of version 350, this benchmark spends much of +;; its time GCing; it runs 1.5 times as fast in mzscheme3m. + +(module partialsums mzscheme + + (define (roundto digits n) + (let* ([e (expt 10 digits)] + [num (round (abs (* e (inexact->exact n))))]) + (format "~a~a.~a" + (if (negative? n) "-" "") + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + (let ((n (exact->inexact + (string->number + (vector-ref (current-command-line-arguments) 0)))) + + (alt 1) (d2 0) (d3 0) (ds 0) (dc 0) + (s0 0) (s1 0) (s2 0) (s3 0) (s4 0) (s5 0) (s6 0) (s7 0) (s8 0)) + + (let loop ([d 0.0] + (alt 1) (d2 0) (d3 0) (ds 0) (dc 0) + (s0 0) (s1 0) (s2 0) (s3 0) (s4 0) (s5 0) (s6 0) (s7 0) (s8 0)) + (if (= d n #;(+ n 1)) + (let ([format-result + (lambda (str n) + (printf str (roundto 9 n)))]) + + (format-result "~a\t(2/3)^k\n" s0) + (format-result "~a\tk^-0.5\n" s1) + (format-result "~a\t1/k(k+1)\n" s2) + (format-result "~a\tFlint Hills\n" s3) + (format-result "~a\tCookson Hills\n" s4) + (format-result "~a\tHarmonic\n" s5) + (format-result "~a\tRiemann Zeta\n" s6) + (format-result "~a\tAlternating Harmonic\n" s7) + (format-result "~a\tGregory\n" s8)) + + (let* ((d (+ d 1)) + (d2 (* d d)) + (d3 (* d2 d)) + (ds (sin d)) + (dc (cos d)) + + (s0 (+ s0 (expt (/ 2.0 3) (- d 1)))) + (s1 (+ s1 (/ 1 (sqrt d)))) + (s2 (+ s2 (/ 1 (* d (+ d 1))))) + (s3 (+ s3 (/ 1 (* d3 (* ds ds))))) + (s4 (+ s4 (/ 1 (* d3 (* dc dc))))) + (s5 (+ s5 (/ 1 d))) + (s6 (+ s6 (/ 1 d2))) + (s7 (+ s7 (/ alt d))) + (s8 (+ s8 (/ alt (- (* 2 d) 1)))) + (alt (- alt))) + + (loop d + alt d2 d3 ds dc + s0 s1 s2 s3 s4 s5 s6 s7 s8)))))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/pidigits.ss b/collects/tests/mzscheme/benchmarks/shootout/pidigits.ss new file mode 100644 index 0000000000..825212c7ce --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/pidigits.ss @@ -0,0 +1,46 @@ +;; The Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; Based on the MLton version of the benchmark +;; contributed by Scott Cruzen + +;; Note: as of version 350, this benchmark spends most of +;; its time GCing; it runs 3 times as fast in mzscheme3m. + +(module pidigits mzscheme + + (define (floor_ev q r s t x) + (quotient (+ (* q x) r) (+ (* s x) t))) + + (define (comp q r s t q2 r2 s2 t2) + (values (+ (* q q2) (* r s2)) + (+ (* q r2) (* r t2)) + (+ (* s q2) (* t s2)) + (+ (* s r2) (* t t2)))) + + (define (next q r s t) (floor_ev q r s t 3)) + (define (safe? q r s t n) (= n (floor_ev q r s t 4))) + (define (prod q r s t n) (comp 10 (* -10 n) 0 1 q r s t)) + (define (mk q r s t k) (comp q r s t k (* 2 (add1 (* 2 k))) 0 (add1 (* 2 k)))) + + (define (digit k q r s t n row col) + (if (> n 0) + (let ([y (next q r s t)]) + (if (safe? q r s t y) + (let-values ([(q r s t) (prod q r s t y)]) + (if (= col 10) + (let ([row (+ row 10)]) + (printf "\t:~a\n~a" row y) + (digit k q r s t (sub1 n) row 1)) + (begin + (printf "~a" y) + (digit k q r s t(sub1 n) row (add1 col))))) + (let-values ([(q r s t) (mk q r s t k)]) + (digit (add1 k) q r s t n row col)))) + (printf "~a\t:~a\n" + (make-string (- 10 col) #\space) + (+ row col)))) + + (define (digits n) + (digit 1 1 0 0 1 n 0 0)) + + (digits (string->number (vector-ref (current-command-line-arguments) 0)))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/pidigits1.ss b/collects/tests/mzscheme/benchmarks/shootout/pidigits1.ss new file mode 100644 index 0000000000..fce814073b --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/pidigits1.ss @@ -0,0 +1,57 @@ +#!/usr/bin/mzscheme -r +; The Computer Language Shootout +; http://shootout.alioth.debian.org/ +; Sven Hartrumpf 2005-04-12 +; Implements 'Spigot' algorithm origionally due to Stanly Rabinowitz. +; This program is based on an implementation for SCM by Aubrey Jaffer and +; Jerry D. Hedden. + +(module pidigits1 mzscheme + + (define (pi n d) + (let* ((r (inexact->exact (floor (exp (* d (log 10)))))) ; 10^d + (p (+ (quotient n d) 1)) + (m (quotient (* p d 3322) 1000)) + (a (make-vector (+ m 1) 2)) + (out (current-output-port))) + (vector-set! a m 4) + (let j-loop ([b 2][digits 0]) + (if (= digits n) + ;; Add whitespace for ungenerated digits + (let ([left (modulo digits 10)]) + (unless (zero? left) + (fprintf out "~a\t:~a\n" (make-string (- 10 left) #\space) n))) + ;; Compute more digits + (let loop ([k m][q 0]) + (if (zero? k) + (let* ((s (let ([s (number->string (+ b (quotient q r)))]) + (if (zero? digits) + s + (string-append (make-string (- d (string-length s)) #\0) s))))) + (j-loop (remainder q r) + (print-digits out s 0 (string-length s) digits n))) + (let ([q (+ q (* (vector-ref a k) r))]) + (let ((t (+ (* k 2) 1))) + (let-values ([(qt rr) (quotient/remainder q t)]) + (vector-set! a k rr) + (loop (sub1 k) (* k qt))))))))))) + + (define (print-digits out s start end digits n) + (let* ([len (- end start)] + [cnt (min len (- n digits) (- 10 (modulo digits 10)) len)]) + (if (zero? cnt) + digits + (begin + (write-string s out start (+ start cnt)) + (let ([digits (+ digits cnt)]) + (when (zero? (modulo digits 10)) + (fprintf out "\t:~a\n" digits)) + (print-digits out s (+ start cnt) end digits n)))))) + + (define (main args) + (let ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0))))) + (pi n 10))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/random.ss b/collects/tests/mzscheme/benchmarks/shootout/random.ss new file mode 100644 index 0000000000..4d29330197 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/random.ss @@ -0,0 +1,40 @@ +;;; http://shootout.alioth.debian.org/ +;;; Random implementation, by Jens Axel Sogaard +;;; +;;; Modified for proper string output by Brent Fulgham + +(module random mzscheme + (provide main) + + (define IM 139968) + (define IA 3877) + (define IC 29573) + + (define gen_random + (let ((LAST 42)) + (lambda (max) + (set! LAST (modulo (+ (* LAST IA) IC) IM)) + (/ (* max LAST) IM)))) + + (define (roundto digits num) + (let* ([e (expt 10 digits)] + [num (round (* e (inexact->exact num)))]) + (format "~a.~a" + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + (define (main args) + (let ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0))))) + (let loop ((iter n)) + (if (> iter 1) + (begin + (gen_random 100.0) + (loop (- iter 1))))) + (printf "~a~%" + (roundto 9 (gen_random 100.0))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/recursive.ss b/collects/tests/mzscheme/benchmarks/shootout/recursive.ss new file mode 100644 index 0000000000..47a8043bd5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/recursive.ss @@ -0,0 +1,65 @@ +;; --------------------------------------------------------------------- +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Code based on / inspired by existing, relevant Shootout submissions +;; +;; Derived from the Chicken variant, which was +;; Contributed by Anthony Borla +;; --------------------------------------------------------------------- + +(module recursive mzscheme + + ;; ------------------------------- + + (define (ack m n) + (cond ((zero? m) (+ n 1)) + ((zero? n) (ack (- m 1) 1)) + (else (ack (- m 1) (ack m (- n 1)))))) + + ;; -------------- + + (define (fib n) + (cond ((< n 2) 1) + (else (+ (fib (- n 2)) (fib (- n 1)))))) + + (define (fibflt n) + (cond ((< n 2.0) 1.0) + (else (+ (fibflt (- n 2.0)) (fibflt (- n 1.0)))))) + + ;; -------------- + + (define (tak x y z) + (cond ((not (< y x)) z) + (else (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))))) + + (define (takflt x y z) + (cond ((not (< y x)) z) + (else (takflt (takflt (- x 1.0) y z) (takflt (- y 1.0) z x) (takflt (- z 1.0) x y))))) + + ;; ------------------------------- + + (define (roundto digits n) + (let* ([e (expt 10 digits)] + [num (round (* e (inexact->exact n)))]) + (format "~a.~a" + (quotient num e) + (substring (string-append (number->string (remainder num e)) + (make-string digits #\0)) + 0 digits)))) + + (define (main args) + (let ((n (string->number (vector-ref args 0)))) + + (printf "Ack(3,~A): ~A~%" n (ack 3 n)) + (printf "Fib(~a): ~a~%" (roundto 1 (+ 27.0 n)) (roundto 1 (fibflt (+ 27.0 n)))) + + (set! n (- n 1)) + (printf "Tak(~A,~A,~A): ~A~%" (* n 3) (* n 2) n (tak (* n 3) (* n 2) n)) + + (printf "Fib(3): ~A~%" (fib 3)) + (printf "Tak(3.0,2.0,1.0): ~a~%" (roundto 1 (takflt 3.0 2.0 1.0))))) + + ;; ------------------------------- + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/regexmatch.ss b/collects/tests/mzscheme/benchmarks/shootout/regexmatch.ss new file mode 100644 index 0000000000..9fe2f0c9fd --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/regexmatch.ss @@ -0,0 +1,59 @@ +;; $Id: regexmatch-mzscheme.code,v 1.9 2006/06/21 15:05:29 bfulgham Exp $ +;;; http://shootout.alioth.debian.org/ +;;; +;;; Based on the Chicken implementation +;;; Contributed by Brent Fulgham + +;; Uses byte regexps instead of string regexps for a fairer comparison + +;; NOTE: the running time of this benchmark is dominated by +;; construction of the `num' string. + +(module regexmatch mzscheme + (define rx + (string-append + "(?:^|[^0-9\\(])" ; (1) preceeding non-digit or bol + "(" ; (2) area code + "\\(([0-9][0-9][0-9])\\)" ; (3) is either 3 digits in parens + "|" ; or + "([0-9][0-9][0-9])" ; (4) just 3 digits + ")" ; end of area code + " " ; area code is followed by one space + "([0-9][0-9][0-9])" ; (5) exchange is 3 digits + "[ -]" ; separator is either space or dash + "([0-9][0-9][0-9][0-9])" ; (6) last 4 digits + "(?:[^0-9]|$)" ; must be followed by a non-digit + )) + + + (define (main args) + (let ((n (if (= (vector-length args) 0) + "1" + (vector-ref args 0))) + (phonelines '()) + (rx (byte-regexp (string->bytes/utf-8 rx))) + (count 0)) + (let loop ((line (read-bytes-line))) + (cond ((eof-object? line) #f) + (else + (set! phonelines (cons line phonelines)) + (loop (read-line))))) + (set! phonelines (reverse! phonelines)) + (do ([n (string->number n) (sub1 n)]) + ((negative? n)) + (let loop ((phones phonelines) + (count 0)) + (if (null? phones) + count + (let ([m (regexp-match rx (car phones))]) + (if m + (let-values ([(a1 a2 a3 exch numb) (apply values (cdr m))]) + (let* ([area (and a1 (or a2 a3))] + [num (bytes-append #"(" area #") " exch #"-" numb)] + [count (add1 count)]) + (when (zero? n) + (printf "~a: ~a~n" count num)) + (loop (cdr phones) count))) + (loop (cdr phones) count)))))))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/regexpdna.ss b/collects/tests/mzscheme/benchmarks/shootout/regexpdna.ss new file mode 100644 index 0000000000..6196e63aaf --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/regexpdna.ss @@ -0,0 +1,105 @@ +;; --------------------------------------------------------------------- +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Tested with PCRE [compiler must be built with PCRE already installed +;; else other regex routines (with different behaviours) will be used]. +;; Regex performance appears reasonable, but file loading [of 'large' +;; files] performance requires tweaking to effect a significant improvement. +;; +;; Contributed by Anthony Borla +;; --------------------------------------------------------------------- + +(module regexpdna mzscheme + + (require (lib "port.ss")) + + ;; ------------------------------- + + (define VARIANTS + '(#"agggtaaa|tttaccct" #"[cgt]gggtaaa|tttaccc[acg]" #"a[act]ggtaaa|tttacc[agt]t" + #"ag[act]gtaaa|tttac[agt]ct" #"agg[act]taaa|ttta[agt]cct" #"aggg[acg]aaa|ttt[cgt]ccct" + #"agggt[cgt]aa|tt[acg]accct" #"agggta[cgt]a|t[acg]taccct" #"agggtaa[cgt]|[acg]ttaccct")) + + + (define IUBS + '((#"B" #"(c|g|t)") (#"D" #"(a|g|t)") (#"H" #"(a|c|t)") + (#"K" #"(g|t)") (#"M" #"(a|c)") (#"N" #"(a|c|g|t)") + (#"R" #"(a|g)") (#"S" #"(c|g)") (#"V" #"(a|c|g)") + (#"W" #"(a|t)") (#"Y" #"(c|t)"))) + + ;; ------------------------------- + + (define (ci-byte-regexp s) + (byte-regexp (ci-pattern s))) + (define (ci-pattern s) + (let ([m (regexp-match #rx#"^(.*)\\[([^]]*)\\](.*)$" s)]) + (if m + (bytes-append (ci-pattern (cadr m)) + #"[" + (regexp-replace* #rx#"[a-zA-Z]" (caddr m) both-cases) + #"]" + (ci-pattern (cadddr m))) + (regexp-replace* #rx#"[a-zA-Z]" s (lambda (s) + (string->bytes/latin-1 + (format "[~a]" (both-cases s)))))))) + (define (both-cases s) + (string->bytes/latin-1 + (format "~a~a" + (string-downcase (bytes->string/latin-1 s)) + (string-upcase (bytes->string/latin-1 s))))) + + ;; ------------------------------- + + (define (match-count str rx offset cnt) + (let ([m (regexp-match-positions rx str offset)]) + (if m + (match-count str rx (cdar m) (add1 cnt)) + cnt))) + + ;; -------------- + + (define (replace-all rx str new) + (let ([out (open-output-bytes)]) + (let loop ([pos 0]) + (let ([m (regexp-match-positions rx str pos)]) + (if m + (begin + (write-bytes str out pos (caar m)) + (write-bytes new out) + (loop (cdar m))) + (write-bytes str out pos)))) + (get-output-bytes out))) + + ;; ------------------------------- + + (define (input->bytes) + (let ([b (open-output-bytes)]) + (copy-port (current-input-port) b) + (get-output-bytes b))) + + ;; ------------------------------- + + ;; Load sequence and record its length + (let* ([orig (input->bytes)] + [filtered (replace-all #rx#"(>.*?\n)|\n" orig #"")]) + + ;; Perform regexp counts + (for-each + (lambda (i) + (printf "~a ~a\n" i (match-count filtered (ci-byte-regexp i) 0 0))) + VARIANTS) + + ;; Perform regexp replacements, and record sequence length + (let ([replaced + (let loop ([sequence filtered] + [IUBS IUBS]) + (if (null? IUBS) + sequence + (loop (replace-all (byte-regexp (caar IUBS)) sequence (cadar IUBS)) + (cdr IUBS))))]) + ;; Print statistics + (printf "~%~A~%~A~%~A~%" + (bytes-length orig) + (bytes-length filtered) + (bytes-length replaced))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/reversecomplement.ss b/collects/tests/mzscheme/benchmarks/shootout/reversecomplement.ss new file mode 100644 index 0000000000..6c40fda020 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/reversecomplement.ss @@ -0,0 +1,60 @@ + +(module reversecomplement mzscheme + + (define translation (make-vector 128)) + + (for-each (lambda (from-to) + (let ([char (lambda (sym) + (string-ref (symbol->string sym) 0))]) + (let ([from (char (car from-to))] + [to (char->integer (char-upcase (char (cadr from-to))))]) + (vector-set! translation (char->integer from) to) + (vector-set! translation (char->integer (char-upcase from)) to)))) + '([a t] + [c g] + [g c] + [t a] + [u a] + [m k] + [r y] + [w w] + [s s] + [y R] + [k M] + [v b] + [h d] + [d h] + [b v] + [n n])) + + (define (output lines) + (let* ([str (apply bytes-append lines)] + [o (current-output-port)] + [len (bytes-length str)]) + (let loop ([offset 0]) + (when (< offset len) + (write-bytes str o offset (min len (+ offset 60))) + (newline o) + (loop (+ offset 60)))))) + + (let ([in (current-input-port)]) + (let loop ([accum null]) + (let ([l (read-bytes-line in)]) + (if (eof-object? l) + (output accum) + (cond + [(regexp-match #rx#"^>" l) + (output accum) + (printf "~a\n" l) + (loop null)] + [else + (let* ([len (bytes-length l)] + [dest (make-bytes len)]) + (let loop ([i 0][j (- len 1)]) + (unless (= i len) + (bytes-set! dest + j + (vector-ref translation (bytes-ref l i))) + (loop (add1 i) (sub1 j)))) + (loop (cons dest accum)))])))))) + diff --git a/collects/tests/mzscheme/benchmarks/shootout/reversefile.ss b/collects/tests/mzscheme/benchmarks/shootout/reversefile.ss new file mode 100644 index 0000000000..73b2f84735 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/reversefile.ss @@ -0,0 +1,13 @@ +;;; -*- mode: scheme -*- +;;; $Id: reversefile-mzscheme.code,v 1.10 2006/06/21 15:05:29 bfulgham Exp $ +;;; http://shootout.alioth.debian.org/ +;;; Provided by Bengt Kleberg + +(module reversefile mzscheme + (let ([inport (current-input-port)]) + (let rev ([lines null]) + (let ([line (read-bytes-line inport)]) + (if (eof-object? line) + (for-each (lambda (l) (printf "~a\n" l)) + lines) + (rev (cons line lines))))))) \ No newline at end of file diff --git a/collects/tests/mzscheme/benchmarks/shootout/run.ss b/collects/tests/mzscheme/benchmarks/shootout/run.ss new file mode 100644 index 0000000000..920d050066 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/run.ss @@ -0,0 +1,54 @@ +(module run mzscheme + (define input-map + '( + ("ackermann.ss" . "11") + ("ary.ss" . "9000") + ("binarytrees.ss" . "16") + ("chameneos.ss") + ("cheapconcurrency.ss") + ("echo.ss" . "150000") + ("except.ss" . "2500000") + ("fannkuch.ss") + ("fasta.ss") + ("fibo.ss" . "32") + ("hash.ss" . "100000") + ("hash2.ss" . "200") + ("heapsort.ss" . "100000") + ("lists.ss" . "18") + ("mandelbrot.ss") + ("matrix.ss" . "600") + ("moments.ss" . "200") + ("nbody.ss") + ("nestedloop.ss" . "18") + ("nsieve.ss") + ("nsievebits.ss") + ("partialsums.ss") + ("pidigits.ss") + ("pidigits1.ss") + ("random.ss" . "900000") + ("recursive.ss") + ("regexmatch.ss") + ("regexpdna.ss") + ("reversecomplement.ss") + ("reversefile.ss") + ("sieve.ss" . "1200") + ("spellcheck.ss") + ("strcat.ss" . "40000") + ("sumcol.ss") + ("wc.ss") + ("wordfreq.ss") + )) + + (let ([len (vector-length (current-command-line-arguments))]) + (unless (= 1 len) + (error 'run "provide ~athe name of a benchmark on the command line" + (if (zero? len) "" "ONLY ")))) + + (let ([prog (vector-ref (current-command-line-arguments) 0)]) + (let ([m (assoc prog input-map)]) + (unless m + (error 'run "cannot find input for ~a" prog)) + (when (null? (cdr m)) + (error 'run "don't know input for ~a" prog)) + (parameterize ([current-command-line-arguments (vector (cdr m))]) + (time (dynamic-require prog #f)))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/sieve.ss b/collects/tests/mzscheme/benchmarks/shootout/sieve.ss new file mode 100644 index 0000000000..f0d25df276 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/sieve.ss @@ -0,0 +1,25 @@ +(module sieve mzscheme + + (define (main args) + (let ((n (if (= (vector-length args) 0) + 1 + (string->number (vector-ref args 0)))) + (count 0) + (flags (make-vector 8192))) + (let loop ((iter n)) + (if (> iter 0) + (begin + (do ((i 0 (+ i 1))) ((>= i 8192)) (vector-set! flags i #t)) + (set! count 0) + (do ((i 2 (+ 1 i))) + ((>= i 8192)) + (if (vector-ref flags i) + (begin + (do ((k (+ i i) (+ k i))) + ((>= k 8192)) + (vector-set! flags k #f)) + (set! count (+ 1 count))))) + (loop (- iter 1))))) + (display "Count: ") (display count) (newline))) + + (main (current-command-line-arguments))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/spellcheck.ss b/collects/tests/mzscheme/benchmarks/shootout/spellcheck.ss new file mode 100644 index 0000000000..ee8eaed904 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/spellcheck.ss @@ -0,0 +1,23 @@ +;;; The Great Computer Language Shootout +;;; http://shootout.alioth.debian.org/ +;;; +;;; spellcheck benchmark + +(module spellcheck mzscheme + (define dict (make-hash-table 'equal)) + + (with-input-from-file "Usr.Dict.Words" + (lambda () + (let loop () + (let ([r (read-bytes-line)]) + (unless (eof-object? r) + (hash-table-put! dict r #t) + (loop)))))) + + (let ([in (current-input-port)]) + (let loop () + (let ([w (read-bytes-line in)]) + (unless (eof-object? w) + (unless (hash-table-get dict w (lambda () #f)) + (printf "~a\n" w)) + (loop)))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/strcat.ss b/collects/tests/mzscheme/benchmarks/shootout/strcat.ss new file mode 100644 index 0000000000..6f951c13d5 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/strcat.ss @@ -0,0 +1,35 @@ +; strcat.scm + +;;; SPECIFICATION + +;For this test, each program should be implemented in the same way, +;according to the following specification. +; +; pseudocode for strcat test +; +; s is initialized to the null string +; repeat N times: +; append "hello\n" to s +; count the number of individual characters in s +; print the count + +; There should be N distinct string append statements done in a loop. +; After each append the resultant string should be 6 characters +; longer (the length of "hello\n"). +; s should be a string, string buffer, or character array. +; The program should not construct a list of strings and join it. + +(module strcat mzscheme + (define p (open-output-bytes)) + + (define hello #"hello\n") + + (let loop ([n (string->number + (vector-ref (current-command-line-arguments) 0))]) + (unless (zero? n) + (display hello p) + ;; At this point, (get-output-bytes p) would + ;; return the byte string accumulated so far. + (loop (sub1 n)))) + + (printf "~a\n" (file-position p))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/sumcol.ss b/collects/tests/mzscheme/benchmarks/shootout/sumcol.ss new file mode 100644 index 0000000000..8d26053590 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/sumcol.ss @@ -0,0 +1,10 @@ +;;; http://shootout.alioth.debian.org/ +;;; +;;; Contributed by Eli Barzilay + +(module sumcol mzscheme + (let loop ([acc 0]) + (let ([n (read)]) + (if (eof-object? n) + (printf "~a\n" acc) + (loop (+ acc n)))))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/wc.ss b/collects/tests/mzscheme/benchmarks/shootout/wc.ss new file mode 100644 index 0000000000..2b37101c61 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/wc.ss @@ -0,0 +1,18 @@ +; +; Faster, more idiomatic Scheme by Neil Van Dyke +; + +(module wc mzscheme + (define (main iport) + (apply printf "~s ~s ~s\n" + (let wc ((i #f) (lines 0) (words 0) (chars 0)) + (let ((x (read-char iport))) + (if (eof-object? x) + (list lines words chars) + (case x + ((#\newline) (wc #f (add1 lines) words (add1 chars))) + ((#\space #\tab) (wc #f lines words (add1 chars))) + (else + (wc #t lines (if i words (add1 words)) (add1 chars))))))))) + + (main (current-input-port))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/wordfreq.ss b/collects/tests/mzscheme/benchmarks/shootout/wordfreq.ss new file mode 100644 index 0000000000..277c6316f3 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/wordfreq.ss @@ -0,0 +1,32 @@ +; $Id: wordfreq-mzscheme.code,v 1.10 2006/06/21 15:05:34 bfulgham Exp $ +; http://shootout.alioth.debian.org/ +; wordfreq.mzscheme by Grzegorz Chrupaa +; Updated and corrected by Brent Fulgham +; Re-written by Matthew Flatt with some inspriation from the Python example + +(module wordfreq mzscheme + (require (lib "list.ss")) + + (define t (make-hash-table 'equal)) + + (define (register-word! s) + (let ([s (string-downcase (bytes->string/utf-8 s))]) + (hash-table-put! t s (add1 (hash-table-get t s (lambda () 0)))))) + + (let ([in (current-input-port)]) + (let loop () + (let ([m (regexp-match #rx#"[a-zA-Z]+" in)]) + (when m + (register-word! (car m)) + (loop))))) + + (for-each display + (sort (hash-table-map + t + (lambda (word count) + (let ((count (number->string count))) + (format"~a~a ~a~%" + (make-string (- 7 (string-length count)) #\space) + count + word)))) + string>?))) \ No newline at end of file