operator.scm 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. ;;;; Operators
  21. (declare (usual-integrations))
  22. (define (o:type o) operator-type-tag)
  23. (define (o:type-predicate o) operator?)
  24. (define (o:arity o)
  25. (operator-arity o))
  26. #|;;; In GENERIC.SCM
  27. (define (make-operator p #!optional name subtype arity #!rest opts)
  28. (if (default-object? name) (set! name #f))
  29. (if (default-object? subtype) (set! subtype #f))
  30. (if (default-object? arity) (set! arity (procedure-arity p)))
  31. (make-apply-hook p `(,operator-type-tag ,subtype ,name ,arity ,@opts)))
  32. |#
  33. (define (make-op p name subtype arity opts)
  34. (make-apply-hook p `(,operator-type-tag ,subtype ,name ,arity ,@opts)))
  35. (define (operator-procedure op)
  36. (assert (operator? op))
  37. (apply-hook-procedure op))
  38. (define (operator-subtype op)
  39. (assert (operator? op))
  40. (cadr (apply-hook-extra op)))
  41. (define (operator-name op)
  42. (assert (operator? op))
  43. (caddr (apply-hook-extra op)))
  44. (define (operator-arity op)
  45. (assert (operator? op))
  46. (cadddr (apply-hook-extra op)))
  47. (define (operator-optionals op)
  48. (assert (operator? op))
  49. (cddddr (apply-hook-extra op)))
  50. (define (simple-operator? op)
  51. (and (operator? op)
  52. (not (operator-subtype op))))
  53. (define (set-operator-optionals! op value)
  54. (assert (operator? op))
  55. (set-cdr! (cdddr (apply-hook-extra op)) value)
  56. op)
  57. (define (operator-merge-subtypes op1 op2)
  58. (let ((t1 (operator-subtype op1))
  59. (t2 (operator-subtype op2)))
  60. (cond ((eq? t1 t2) t1)
  61. ((not t1) t2)
  62. ((not t2) t1)
  63. (else
  64. (error "Incompatible subtypes -- OPERATOR" t1 t2)))))
  65. (define (operator-merge-arities op1 op2)
  66. (joint-arity (operator-arity op1) (operator-arity op2)))
  67. (define (operator-merge-optionals op1 op2)
  68. (list-union (operator-optionals op1)
  69. (operator-optionals op2)))
  70. (define (o:zero-like op)
  71. (assert (equal? (operator-arity op) *exactly-one*) "o:zero-like")
  72. (make-op (lambda (f) (g:zero-like f))
  73. 'zero
  74. (operator-subtype op)
  75. (operator-arity op)
  76. (operator-optionals op)))
  77. (define (o:one-like op)
  78. (assert (equal? (operator-arity op) *exactly-one*) "o:one-like")
  79. (make-op g:identity
  80. 'identity
  81. (operator-subtype op)
  82. (operator-arity op)
  83. (operator-optionals op)))
  84. (define o:identity
  85. (make-operator g:identity 'identity))
  86. (define (o:+ op1 op2)
  87. (make-op (lambda fs
  88. (g:+ (apply op1 fs) (apply op2 fs)))
  89. `(+ ,(operator-name op1)
  90. ,(operator-name op2))
  91. (operator-merge-subtypes op1 op2)
  92. (operator-merge-arities op1 op2)
  93. (operator-merge-optionals op1 op2)))
  94. (define (o:- op1 op2)
  95. (make-op (lambda fs
  96. (g:- (apply op1 fs) (apply op2 fs)))
  97. `(- ,(operator-name op1)
  98. ,(operator-name op2))
  99. (operator-merge-subtypes op1 op2)
  100. (operator-merge-arities op1 op2)
  101. (operator-merge-optionals op1 op2)))
  102. (define (o:o+f op f)
  103. (let ((h (coerce-to-function f)))
  104. (make-op (lambda (g)
  105. (g:+ (op g)
  106. (g:compose h g)))
  107. `(+ ,(operator-name op) ,(procedure-expression h))
  108. (operator-subtype op)
  109. (operator-arity op)
  110. (operator-optionals op))))
  111. (define (o:f+o f op)
  112. (let ((h (coerce-to-function f)))
  113. (make-op (lambda (g)
  114. (g:+ (g:compose h g)
  115. (op g)))
  116. `(+ ,(procedure-expression h) ,(operator-name op))
  117. (operator-subtype op)
  118. (operator-arity op)
  119. (operator-optionals op))))
  120. (define (o:o-f op f)
  121. (let ((h (coerce-to-function f)))
  122. (make-op (lambda (g)
  123. (g:- (op g)
  124. (g:compose h g)))
  125. `(- ,(operator-name op) ,(procedure-expression h))
  126. (operator-subtype op)
  127. (operator-arity op)
  128. (operator-optionals op))))
  129. (define (o:f-o f op)
  130. (let ((h (coerce-to-function f)))
  131. (make-op (lambda (g)
  132. (g:- (g:compose h g)
  133. (op g)))
  134. `(- ,(procedure-expression h) ,(operator-name op))
  135. (operator-subtype op)
  136. (operator-arity op)
  137. (operator-optionals op))))
  138. (define (o:negate op)
  139. (make-op (lambda fs
  140. (g:negate (apply op fs)))
  141. `(- ,(operator-name op))
  142. (operator-subtype op)
  143. (operator-arity op)
  144. (operator-optionals op)))
  145. (define (o:* op1 op2)
  146. (let ((subtype
  147. (operator-merge-subtypes op1 op2)))
  148. (if (procedure? subtype)
  149. (subtype op1 op2)
  150. (make-op (compose op1 op2)
  151. `(* ,(operator-name op1)
  152. ,(operator-name op2))
  153. subtype
  154. (operator-arity op2)
  155. (operator-merge-optionals op1 op2)))))
  156. (define (o:f*o f op)
  157. (make-op (lambda gs
  158. (g:* f (apply op gs)))
  159. `(* ,(procedure-expression
  160. (coerce-to-function f))
  161. ,(operator-name op))
  162. (operator-subtype op)
  163. (operator-arity op)
  164. (operator-optionals op)))
  165. (define (o:o*f op f)
  166. (make-op (lambda gs
  167. (apply op (map (lambda (g) (g:* f g)) gs)))
  168. `(* ,(operator-name op)
  169. ,(procedure-expression
  170. (coerce-to-function f)))
  171. (operator-subtype op)
  172. (operator-arity op)
  173. (operator-optionals op)))
  174. (define (o:o/n op n)
  175. (make-op (lambda gs
  176. (g:* (/ 1 n) (apply op gs)))
  177. `(/ ,(operator-name op) ,n)
  178. (operator-subtype op)
  179. (operator-arity op)
  180. (operator-optionals op)))
  181. (define (o:expt op n)
  182. (assert (equal? (operator-arity op) *exactly-one*) "o:expt")
  183. (make-op (iterated op n o:identity)
  184. `(expt ,(operator-name op) ,n)
  185. (operator-subtype op)
  186. (operator-arity op)
  187. (operator-optionals op)))
  188. (define (o:exp op)
  189. (assert (equal? (operator-arity op) *exactly-one*) "o:exp")
  190. (make-op (lambda (g)
  191. (lambda x
  192. ;;; FBE
  193. ;;(g:apply ((series:value exp-series (list op)) g) x)
  194. (g:apply (g:apply (series:value exp-series (list op)) (list g)) x)
  195. ))
  196. `(exp ,(operator-name op))
  197. (operator-subtype op)
  198. (operator-arity op)
  199. (operator-optionals op)))
  200. (define (o:cos op)
  201. (assert (equal? (operator-arity op) *exactly-one*) "o:cos")
  202. (make-op (lambda (g)
  203. (lambda x
  204. ;;; FBE
  205. ;;(g:apply ((series:value cos-series (list op)) g) x)
  206. (g:apply (g:apply (series:value cos-series (list op)) (list g)) x)
  207. ))
  208. `(cos ,(operator-name op))
  209. (operator-subtype op)
  210. (operator-arity op)
  211. (operator-optionals op)))
  212. (define (o:sin op)
  213. (assert (equal? (operator-arity op) *exactly-one*) "o:sin")
  214. (make-op (lambda (g)
  215. (lambda x
  216. ;; FBE
  217. ;;(g:apply ((series:value sin-series (list op)) g) x)
  218. (g:apply (g:apply (series:value sin-series (list op)) (list g)) x)
  219. ))
  220. `(sin ,(operator-name op))
  221. (operator-subtype op)
  222. (operator-arity op)
  223. (operator-optionals op)))
  224. ;;; Optional order argument for exponentiation of operators.
  225. ;;; (((expn D 2) g) x)
  226. ;;; = (((exp D)
  227. ;;; (lambda (eps)
  228. ;;; (((+ 1 (* (expt eps 2) D) (* 1/2 (expt eps 4) (expt D 2)) ...) g) x))
  229. ;;; 0)
  230. ;;; This is (exp (* (expt eps 2) D)) written as a power series in eps.
  231. (define* (expn op #:optional exponent)
  232. (assert (operator? op))
  233. (assert (equal? (operator-arity op) *exactly-one*) "o:expn")
  234. (if (default-object? exponent)
  235. (o:exp op)
  236. (make-op
  237. (lambda (g)
  238. (lambda x
  239. ;; FBE
  240. (g:apply ;; ((series:inflate (series:value exp-series (list op))
  241. ;; exponent)
  242. ;; g)
  243. (g:apply (series:inflate (series:value exp-series (list op))
  244. exponent)
  245. (list g))
  246. x)))
  247. `(exp ,(operator-name op))
  248. (operator-subtype op)
  249. (operator-arity op)
  250. (operator-optionals op))))
  251. (define %kernel-operator-dummy-1
  252. (begin
  253. (assign-operation 'type o:type operator?)
  254. (assign-operation 'type-predicate o:type-predicate operator?)
  255. (assign-operation 'arity o:arity operator?)
  256. (assign-operation 'zero-like o:zero-like simple-operator?)
  257. (assign-operation 'one-like o:one-like operator?)
  258. (assign-operation 'identity-like o:one-like operator?)
  259. (assign-operation '+ o:+ operator? operator?)
  260. (assign-operation '+ o:o+f operator? not-operator?)
  261. (assign-operation '+ o:f+o not-operator? operator?)
  262. (assign-operation '- o:- operator? operator?)
  263. (assign-operation '- o:o-f operator? not-operator?)
  264. (assign-operation '- o:f-o not-operator? operator?)
  265. (assign-operation '* o:* operator? operator?)
  266. (assign-operation '* o:o*f operator? not-operator?)
  267. (assign-operation '* o:f*o not-operator? operator?)
  268. (assign-operation '/ o:o/n operator? numerical-quantity?)
  269. (assign-operation 'negate o:negate operator?)
  270. (assign-operation 'expt o:expt operator? exact-integer?)
  271. (assign-operation 'exp o:exp operator?)
  272. (assign-operation 'sin o:sin operator?)
  273. (assign-operation 'cos o:cos operator?)))