lattice.sch 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. ; This benchmark was obtained from Andrew Wright.
  2. ; 970215 / wdc Added lattice-benchmark.
  3. ; Given a comparison routine that returns one of
  4. ; less
  5. ; more
  6. ; equal
  7. ; uncomparable
  8. ; return a new comparison routine that applies to sequences.
  9. (define lexico
  10. (lambda (base)
  11. (define lex-fixed
  12. (lambda (fixed lhs rhs)
  13. (define check
  14. (lambda (lhs rhs)
  15. (if (null? lhs)
  16. fixed
  17. (let ((probe
  18. (base (car lhs)
  19. (car rhs))))
  20. (if (or (eq? probe 'equal)
  21. (eq? probe fixed))
  22. (check (cdr lhs)
  23. (cdr rhs))
  24. 'uncomparable)))))
  25. (check lhs rhs)))
  26. (define lex-first
  27. (lambda (lhs rhs)
  28. (if (null? lhs)
  29. 'equal
  30. (let ((probe
  31. (base (car lhs)
  32. (car rhs))))
  33. (case probe
  34. ((less more)
  35. (lex-fixed probe
  36. (cdr lhs)
  37. (cdr rhs)))
  38. ((equal)
  39. (lex-first (cdr lhs)
  40. (cdr rhs)))
  41. ((uncomparable)
  42. 'uncomparable))))))
  43. lex-first))
  44. (define (make-lattice elem-list cmp-func)
  45. (cons elem-list cmp-func))
  46. (define lattice->elements car)
  47. (define lattice->cmp cdr)
  48. ; Select elements of a list which pass some test.
  49. (define zulu-select
  50. (lambda (test lst)
  51. (define select-a
  52. (lambda (ac lst)
  53. (if (null? lst)
  54. (reverse! ac)
  55. (select-a
  56. (let ((head (car lst)))
  57. (if (test head)
  58. (cons head ac)
  59. ac))
  60. (cdr lst)))))
  61. (select-a '() lst)))
  62. (define reverse!
  63. (letrec ((rotate
  64. (lambda (fo fum)
  65. (let ((next (cdr fo)))
  66. (set-cdr! fo fum)
  67. (if (null? next)
  68. fo
  69. (rotate next fo))))))
  70. (lambda (lst)
  71. (if (null? lst)
  72. '()
  73. (rotate lst '())))))
  74. ; Select elements of a list which pass some test and map a function
  75. ; over the result. Note, only efficiency prevents this from being the
  76. ; composition of select and map.
  77. (define select-map
  78. (lambda (test func lst)
  79. (define select-a
  80. (lambda (ac lst)
  81. (if (null? lst)
  82. (reverse! ac)
  83. (select-a
  84. (let ((head (car lst)))
  85. (if (test head)
  86. (cons (func head)
  87. ac)
  88. ac))
  89. (cdr lst)))))
  90. (select-a '() lst)))
  91. ; This version of map-and tail-recurses on the last test.
  92. (define map-and
  93. (lambda (proc lst)
  94. (if (null? lst)
  95. #T
  96. (letrec ((drudge
  97. (lambda (lst)
  98. (let ((rest (cdr lst)))
  99. (if (null? rest)
  100. (proc (car lst))
  101. (and (proc (car lst))
  102. (drudge rest)))))))
  103. (drudge lst)))))
  104. (define (maps-1 source target pas new)
  105. (let ((scmp (lattice->cmp source))
  106. (tcmp (lattice->cmp target)))
  107. (let ((less
  108. (select-map
  109. (lambda (p)
  110. (eq? 'less
  111. (scmp (car p) new)))
  112. cdr
  113. pas))
  114. (more
  115. (select-map
  116. (lambda (p)
  117. (eq? 'more
  118. (scmp (car p) new)))
  119. cdr
  120. pas)))
  121. (zulu-select
  122. (lambda (t)
  123. (and
  124. (map-and
  125. (lambda (t2)
  126. (memq (tcmp t2 t) '(less equal)))
  127. less)
  128. (map-and
  129. (lambda (t2)
  130. (memq (tcmp t2 t) '(more equal)))
  131. more)))
  132. (lattice->elements target)))))
  133. (define (maps-rest source target pas rest to-1 to-collect)
  134. (if (null? rest)
  135. (to-1 pas)
  136. (let ((next (car rest))
  137. (rest (cdr rest)))
  138. (to-collect
  139. (map
  140. (lambda (x)
  141. (maps-rest source target
  142. (cons
  143. (cons next x)
  144. pas)
  145. rest
  146. to-1
  147. to-collect))
  148. (maps-1 source target pas next))))))
  149. (define (maps source target)
  150. (make-lattice
  151. (maps-rest source
  152. target
  153. '()
  154. (lattice->elements source)
  155. (lambda (x) (list (map cdr x)))
  156. (lambda (x) (apply append x)))
  157. (lexico (lattice->cmp target))))
  158. (define print-frequency 10000)
  159. (define (count-maps source target)
  160. (let ((count 0))
  161. (maps-rest source
  162. target
  163. '()
  164. (lattice->elements source)
  165. (lambda (x)
  166. (set! count (+ count 1))
  167. (if (= 0 (remainder count print-frequency))
  168. (begin #f))
  169. 1)
  170. (lambda (x) (apply + x)))))
  171. (define (lattice-benchmark)
  172. (run-benchmark "Lattice"
  173. (lambda ()
  174. (let* ((l2
  175. (make-lattice '(low high)
  176. (lambda (lhs rhs)
  177. (case lhs
  178. ((low)
  179. (case rhs
  180. ((low)
  181. 'equal)
  182. ((high)
  183. 'less)
  184. (else
  185. (error 'make-lattice "base" rhs))))
  186. ((high)
  187. (case rhs
  188. ((low)
  189. 'more)
  190. ((high)
  191. 'equal)
  192. (else
  193. (error 'make-lattice "base" rhs))))
  194. (else
  195. (error 'make-lattice "base" lhs))))))
  196. (l3 (maps l2 l2))
  197. (l4 (maps l3 l3)))
  198. (count-maps l2 l2)
  199. (count-maps l3 l3)
  200. (count-maps l2 l3)
  201. (count-maps l3 l2)
  202. (count-maps l4 l4)))))