utils.scm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; UTILS.SCM
  21. ;;; A few utilities
  22. ;;; 5/9/03 (gjs) -- redistributed most list, sets, and table procedures to GENERAL/.
  23. ;;; 9/15/89 (gjs) -- added FORALL, EXISTS; moved ACCUMULATION, INVERSE-ACCUMULATION here.
  24. ;;; 7/16/89 (mh) correcting bug in DEFAULT-LOOKUP
  25. ;;; 9/22/89 (gjs) reduce->a-reduce
  26. (declare (usual-integrations))
  27. (define (do-up low hi proc)
  28. ;; execute PROC for values beginning at LOW up to HI (exclusive)
  29. (if (fix:< low hi)
  30. (begin (proc low)
  31. (do-up (fix:+ low 1) hi proc))))
  32. (define (do-down hi low proc)
  33. ;; execute PROC for values beginning at HI down to LOW (exclusive)
  34. (if (fix:< low hi)
  35. (begin (proc hi)
  36. (do-down (fix:- hi 1) low proc))))
  37. (define (sign x)
  38. (cond ((> x 0) 1)
  39. ((< x 0) -1)
  40. (else 0)))
  41. (define (defer-application f)
  42. (lambda (x)
  43. (if (procedure? x)
  44. (defer-application (compose f x))
  45. (f x))))
  46. #|
  47. ((((defer-application (lambda (x) (* 3 x))) (lambda (x) (+ x 2))) (lambda (x) (/ x 2))) 3)
  48. #| 21/2 |#
  49. |#
  50. (define make-pairwise-test
  51. (lambda (pred)
  52. (lambda args
  53. (define (loop x y rem)
  54. (and (pred x y)
  55. (or (null? rem)
  56. (loop y (car rem) (cdr rem)))))
  57. (if (or (null? args) (null? (cdr args)))
  58. (error "Pred needs 2 args" pred args)
  59. (loop (car args) (cadr args) (cddr args))))))
  60. (define (all-equal? lst)
  61. (define (lp lst)
  62. (if (null? (cdr lst))
  63. #t
  64. (and (equal? (car lst) (cadr lst))
  65. (lp (cdr lst)))))
  66. (if (null? lst)
  67. #t
  68. (lp lst)))
  69. #|
  70. (define accumulation
  71. (lambda (operation identity)
  72. (lambda rest
  73. (define (loop accum rem)
  74. (if (null? rem)
  75. accum
  76. (loop (operation accum (car rem)) (cdr rem))))
  77. (cond ((null? rest) identity)
  78. ((null? (cdr rest)) (car rest))
  79. (else (operation (car rest) (loop (cadr rest) (cddr rest))))))))
  80. |#
  81. (define accumulation
  82. (lambda (operation identity)
  83. (lambda rest
  84. (define (loop accum rem)
  85. (if (null? rem)
  86. accum
  87. (loop (operation accum (car rem)) (cdr rem))))
  88. (cond ((null? rest) identity)
  89. ((null? (cdr rest)) (car rest))
  90. (else (loop (car rest) (cdr rest)))))))
  91. (define inverse-accumulation
  92. (lambda (operation1 operation2 invop identity)
  93. (lambda rest
  94. (define (loop accum rem)
  95. (if (null? rem)
  96. accum
  97. (loop (operation2 accum (car rem)) (cdr rem))))
  98. (cond ((null? rest) identity)
  99. ((null? (cdr rest)) (invop (car rest)))
  100. ((null? (cddr rest)) (operation1 (car rest) (cadr rest)))
  101. (else (operation1 (car rest) (loop (cadr rest) (cddr rest))))))))
  102. (define (left-circular-shift l)
  103. (if (or (null? l) (null? (cdr l)))
  104. l
  105. (append (cdr l) (list (car l)))))
  106. (define (right-circular-shift l)
  107. (if (or (null? l) (null? (cdr l)))
  108. l
  109. (let ((r (reverse l)))
  110. (cons (car r) (reverse! (cdr r))))))
  111. ;;; Functional operators
  112. ;;; Arity is important to special case.
  113. (define *at-least-zero* '(0 . #f))
  114. (define *exactly-zero* '(0 . 0))
  115. (define *at-least-one* '(1 . #f))
  116. (define *exactly-one* '(1 . 1))
  117. (define *at-least-two* '(2 . #f))
  118. (define *exactly-two* '(2 . 2))
  119. (define *at-least-three* '(3 . #f))
  120. (define *exactly-three* '(3 . 3))
  121. (define *one-or-two* '(1 . 2))
  122. (define (exactly-n? arity)
  123. (fix:= (car arity) (cdr arity)))
  124. (define (any-number? arity)
  125. (and (null? (cdr arity))
  126. (fix:= (car arity) 0)))
  127. (define (compose . fs)
  128. (compose-n fs))
  129. (define (compose-n fs)
  130. (define (lp fs)
  131. (cond ((null? (cdr fs)) (car fs))
  132. (else (compose-2 (car fs) (lp (cdr fs))))))
  133. (cond ((null? fs) identity)
  134. ((null? (cdr fs)) (car fs))
  135. (else ;compose-bin preserves arity
  136. (compose-bin (lp (butlast fs))
  137. (car (last-pair fs))))))
  138. (define (identity x) x)
  139. (define (compose-2 f g)
  140. (cond ((pair? g)
  141. (lambda x
  142. (apply f
  143. (map (lambda (gi)
  144. (apply gi x))
  145. g))))
  146. (else
  147. (lambda x
  148. (f (apply g x))))))
  149. (define (compose-bin f g)
  150. (cond ((pair? g)
  151. (let ((a
  152. (a-reduce joint-arity
  153. (map procedure-arity g))))
  154. (cond ((equal? a *at-least-zero*)
  155. (lambda x
  156. (apply f
  157. (map
  158. (lambda (gi)
  159. (apply gi x))
  160. g))))
  161. ((equal? a *exactly-zero*)
  162. (lambda ()
  163. (apply f
  164. (map (lambda (gi)
  165. (gi))
  166. g))))
  167. ((equal? a *at-least-one*)
  168. (lambda (x . y)
  169. (apply f
  170. (map (lambda (gi)
  171. (apply gi x y))
  172. g))))
  173. ((equal? a *exactly-one*)
  174. (lambda (x)
  175. (apply f
  176. (map (lambda (gi)
  177. (gi x))
  178. g))))
  179. ((equal? a *at-least-two*)
  180. (lambda (x y . z)
  181. (apply f
  182. (map (lambda (gi)
  183. (apply gi x y z))
  184. g))))
  185. ((equal? a *exactly-two*)
  186. (lambda (x y)
  187. (apply f
  188. (map (lambda (gi)
  189. (gi x y))
  190. g))))
  191. ((equal? a *at-least-three*)
  192. (lambda (u x y . z)
  193. (apply f
  194. (map (lambda (gi)
  195. (apply gi u x y z))
  196. g))))
  197. ((equal? a *exactly-three*)
  198. (lambda (x y z)
  199. (apply f
  200. (map (lambda (gi)
  201. (gi x y z))
  202. g))))
  203. ((equal? a *one-or-two*)
  204. (lambda* (x #:optional y)
  205. (if (default-object? y)
  206. (apply f
  207. (map (lambda (gi)
  208. (gi x))
  209. g))
  210. (apply f
  211. (map (lambda (gi)
  212. (gi x y))
  213. g)))))
  214. (else
  215. (lambda x
  216. (apply f
  217. (map
  218. (lambda (gi)
  219. (apply gi x))
  220. g)))))))
  221. (else
  222. (let ((a (procedure-arity g)))
  223. (cond ((equal? a *at-least-zero*)
  224. (lambda x
  225. (f (apply g x))))
  226. ((equal? a *exactly-zero*)
  227. (lambda ()
  228. (f (g))))
  229. ((equal? a *at-least-one*)
  230. (lambda (x . y)
  231. (f (apply g x y))))
  232. ((equal? a *exactly-one*)
  233. (lambda (x)
  234. (f (g x))))
  235. ((equal? a *at-least-two*)
  236. (lambda (x y . z)
  237. (f (apply g x y z))))
  238. ((equal? a *exactly-two*)
  239. (lambda (x y)
  240. (f (g x y))))
  241. ((equal? a *at-least-three*)
  242. (lambda (u x y . z)
  243. (f (apply g u x y z))))
  244. ((equal? a *exactly-three*)
  245. (lambda (x y z)
  246. (f (g x y z))))
  247. ((equal? a *one-or-two*)
  248. (lambda* (x #:optional y)
  249. (if (default-object? y)
  250. (f (g x))
  251. (f (g x y)))))
  252. (else
  253. (lambda x
  254. (f (apply g x)))))))))
  255. (define (any? . args) #t)
  256. (define (none? . args) #f)
  257. (define* ((constant x) . y) x)
  258. (define (joint-arity a1 a2)
  259. (if (and a1 a2)
  260. (let ((amin (max (car a1) (car a2)))
  261. (amax
  262. (let ((a1max (cdr a1)) (a2max (cdr a2)))
  263. (if a1max
  264. (if a2max
  265. (min a1max a2max)
  266. a1max)
  267. a2max))))
  268. (if (and amax (fix:< amax amin))
  269. #f
  270. (cons amin amax)))
  271. #f))
  272. (define (a-reduce f l)
  273. (define (loop l)
  274. (if (null? (cdr l))
  275. (car l)
  276. (loop (cons (f (car l) (cadr l)) (cddr l)))))
  277. (if (null? l)
  278. (error "Reduce no elements")
  279. (loop l)))
  280. (define (filter pred l)
  281. (let lp ((l l))
  282. (cond ((null? l) '())
  283. ((pred (car l)) (cons (car l) (lp (cdr l))))
  284. (else (lp (cdr l))))))
  285. (define (make-map f) ; very neat, e.g. ((make-map -) '(3 2) '(1 1)) = '(2 1)
  286. (lambda x (apply map (cons f x))))
  287. (define* ((bracket . fl) . x)
  288. (map (lambda (f) (apply f x))
  289. fl))
  290. (define* ((apply-to-all f) x)
  291. (map f x))
  292. ;;; FBE start
  293. ;; (define* (((nary-combine fnary) . fs) . xs)
  294. ;; (apply fnary
  295. ;; (map (lambda (f) (apply f xs))
  296. ;; fs)))
  297. (define (nary-combine fnary)
  298. (lambda fs
  299. (lambda xs
  300. (apply fnary (map (lambda (f) (apply f xs)) fs)))))
  301. ;; (define* (((binary-combine fbin) f1 f2) . xs)
  302. ;; (fbin (apply f1 xs) (apply f2 xs)))
  303. (define (binary-combine fbin)
  304. (lambda (f1 f2)
  305. (lambda xs
  306. (fbin (apply f1 xs) (apply f2 xs)))))
  307. ;; (define* (((unary-combine funary) f) . xs)
  308. ;; (funary (apply f xs)))
  309. (define (unary-combine funary)
  310. (lambda (f)
  311. (lambda xs
  312. (funary (apply f xs)))))
  313. ;;; FBE end
  314. (define* (iterated f n #:optional id)
  315. (if (fix:< n 0)
  316. (error "I don't know how to invert -- ITERATED" f n)
  317. (let ((ident (if (default-object? id) identity id)))
  318. (if (fix:= n 0)
  319. ident
  320. (let lp ((n n))
  321. (if (fix:= n 1)
  322. f
  323. (compose-2 f (lp (fix:- n 1)))))))))
  324. ;;; Generalization of fixed point stuff
  325. (define (iterate-until-stable f done? x0)
  326. (let lp ((x x0))
  327. (let ((nx (f x)))
  328. (if (done? nx x)
  329. nx
  330. (lp nx)))))
  331. ;;; given a function f of a variable number of arguments, return a new
  332. ;;; function that accepts a single vector argument and calls f with the
  333. ;;; vector elements as arguments
  334. (define (make-function-of-vector f)
  335. (lambda (v)
  336. (apply f (vector->list v))))
  337. ;;; given a function of a single vector argument, return a new function
  338. ;;; that takes multiple arguments, being the vector elements
  339. (define (make-function-of-arguments f)
  340. (lambda args
  341. (f (list->vector args))))
  342. #|
  343. ;;; The following procedure came from SCHEME 6.1.2 RUNTIME
  344. (define alphaless?
  345. (let ()
  346. (define (stringify object)
  347. (cond ((symbol? object) (symbol->string object))
  348. ((string? object) object)
  349. (else (error "ALPHALESS?: Wrong type argument" object))))
  350. (named-lambda (alphaless? x y)
  351. (string<? (stringify x) (stringify y)))))
  352. |#
  353. (define (alphaless? x y)
  354. (cond ((symbol? x)
  355. (cond ((symbol? y) (symbol<? x y))
  356. ((string? y) (string<? (symbol->string x) y))
  357. (else
  358. (error "ALPHALESS?: Wrong type argument" y))))
  359. ((string? x)
  360. (cond ((string? y) (string<? x y))
  361. ((symbol? y) (string<? x (symbol->string y)))
  362. (else
  363. (error "ALPHALESS?: Wrong type argument" y))))
  364. (else
  365. (error "ALPHALESS?: Wrong type argument" x))))
  366. (define (concatenate-names-maker concat-string)
  367. (define (cn strings)
  368. (cond ((null? strings) "")
  369. ((null? (cdr strings)) (car strings))
  370. (else
  371. (a-reduce (lambda (n1 n2)
  372. (string-append n1 concat-string n2))
  373. strings))))
  374. (define (concatenate-names . names)
  375. (cond ((null? names) the-null-symbol)
  376. ((null? (cdr names)) (car names))
  377. (else
  378. (string->symbol
  379. (cn (map symbol->string
  380. (filter (lambda (x)
  381. (not (eq? x the-null-symbol)))
  382. names)))))))
  383. concatenate-names)
  384. (define the-null-symbol (string->symbol ""))
  385. (define concatenate-names (concatenate-names-maker "."))
  386. ;;; Special property of MIT CScheme
  387. (define* (print-depth #:optional newval)
  388. (if (default-object? newval) (set! newval #F))
  389. (if (or (not newval)
  390. (and (integer? newval)
  391. (positive? newval)))
  392. (set! *unparser-list-depth-limit* newval)
  393. (error "PRINT-DEPTH: Wrong type argument" newval)))
  394. (define* (print-breadth #:optional newval)
  395. (if (default-object? newval) (set! newval #F))
  396. (if (or (not newval)
  397. (and (integer? newval)
  398. (positive? newval)))
  399. (set! *unparser-list-breadth-limit* newval)
  400. (error "PRINT-BREADTH: Wrong type argument" newval)))
  401. ;;;for printing things out
  402. (define (wallp-pp p? . objs)
  403. (if p? (for-each pp objs)))
  404. (define (pp-it x)
  405. (pp x)
  406. x)
  407. (define (watch-it wallp message)
  408. (lambda (e)
  409. (if wallp
  410. (begin (newline)
  411. (display message)
  412. (pp e)))
  413. e))
  414. (define* (cpp x #:optional port)
  415. (pp x
  416. (if (default-object? port)
  417. (current-output-port)
  418. port)
  419. ;; as code
  420. true))
  421. ;;; Programs may leave notes here
  422. ;;;: FBE: make parameter
  423. (define *taking-notes* (make-parameter #t))
  424. (define *showing-notes* (make-parameter #f))
  425. ;;; FBE: make a parameter
  426. (define *notes* (make-parameter '()))
  427. (define (note-that! note)
  428. (and note ;fail if note is #f
  429. (begin
  430. (if (*showing-notes*)
  431. (display-note note))
  432. (if (*taking-notes*)
  433. (begin
  434. (*notes* (lset-adjoin equal? (*notes*) note))
  435. 'noted)
  436. 'ignored))))
  437. (define (clear-notes!)
  438. (*last-notes* (*notes*))
  439. (*notes* '()))
  440. (define (display-note note)
  441. (display "#| ")
  442. (newline)
  443. (pp note)
  444. (display "|#")
  445. (newline))
  446. (define *last-notes* (make-parameter '()))
  447. (define *last-notes-shown* (make-parameter '()))
  448. (define (show-notes)
  449. (*last-notes-shown* (*last-notes*))
  450. (newline)
  451. (display "#| ")
  452. (for-each (lambda (note)
  453. (newline)
  454. (pp note)
  455. (let ((sig (eq-get note 'rules)))
  456. (if sig (pp sig))))
  457. (*last-notes*))
  458. (display "|#"))