123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- #| -*-Scheme-*-
- Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
- Institute of Technology
- This file is part of MIT/GNU Scheme.
- MIT/GNU Scheme is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
- MIT/GNU Scheme is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with MIT/GNU Scheme; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
- USA.
- |#
- ;;;; Operators
- (declare (usual-integrations))
- (define (o:type o) operator-type-tag)
- (define (o:type-predicate o) operator?)
- (define (o:arity o)
- (operator-arity o))
- #|;;; In GENERIC.SCM
- (define (make-operator p #!optional name subtype arity #!rest opts)
- (if (default-object? name) (set! name #f))
- (if (default-object? subtype) (set! subtype #f))
- (if (default-object? arity) (set! arity (procedure-arity p)))
- (make-apply-hook p `(,operator-type-tag ,subtype ,name ,arity ,@opts)))
- |#
- (define (make-op p name subtype arity opts)
- (make-apply-hook p `(,operator-type-tag ,subtype ,name ,arity ,@opts)))
- (define (operator-procedure op)
- (assert (operator? op))
- (apply-hook-procedure op))
- (define (operator-subtype op)
- (assert (operator? op))
- (cadr (apply-hook-extra op)))
- (define (operator-name op)
- (assert (operator? op))
- (caddr (apply-hook-extra op)))
- (define (operator-arity op)
- (assert (operator? op))
- (cadddr (apply-hook-extra op)))
- (define (operator-optionals op)
- (assert (operator? op))
- (cddddr (apply-hook-extra op)))
- (define (simple-operator? op)
- (and (operator? op)
- (not (operator-subtype op))))
- (define (set-operator-optionals! op value)
- (assert (operator? op))
- (set-cdr! (cdddr (apply-hook-extra op)) value)
- op)
- (define (operator-merge-subtypes op1 op2)
- (let ((t1 (operator-subtype op1))
- (t2 (operator-subtype op2)))
- (cond ((eq? t1 t2) t1)
- ((not t1) t2)
- ((not t2) t1)
- (else
- (error "Incompatible subtypes -- OPERATOR" t1 t2)))))
- (define (operator-merge-arities op1 op2)
- (joint-arity (operator-arity op1) (operator-arity op2)))
- (define (operator-merge-optionals op1 op2)
- (list-union (operator-optionals op1)
- (operator-optionals op2)))
- (define (o:zero-like op)
- (assert (equal? (operator-arity op) *exactly-one*) "o:zero-like")
- (make-op (lambda (f) (g:zero-like f))
- 'zero
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:one-like op)
- (assert (equal? (operator-arity op) *exactly-one*) "o:one-like")
- (make-op g:identity
- 'identity
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define o:identity
- (make-operator g:identity 'identity))
- (define (o:+ op1 op2)
- (make-op (lambda fs
- (g:+ (apply op1 fs) (apply op2 fs)))
- `(+ ,(operator-name op1)
- ,(operator-name op2))
- (operator-merge-subtypes op1 op2)
- (operator-merge-arities op1 op2)
- (operator-merge-optionals op1 op2)))
- (define (o:- op1 op2)
- (make-op (lambda fs
- (g:- (apply op1 fs) (apply op2 fs)))
- `(- ,(operator-name op1)
- ,(operator-name op2))
- (operator-merge-subtypes op1 op2)
- (operator-merge-arities op1 op2)
- (operator-merge-optionals op1 op2)))
- (define (o:o+f op f)
- (let ((h (coerce-to-function f)))
- (make-op (lambda (g)
- (g:+ (op g)
- (g:compose h g)))
- `(+ ,(operator-name op) ,(procedure-expression h))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op))))
- (define (o:f+o f op)
- (let ((h (coerce-to-function f)))
- (make-op (lambda (g)
- (g:+ (g:compose h g)
- (op g)))
- `(+ ,(procedure-expression h) ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op))))
- (define (o:o-f op f)
- (let ((h (coerce-to-function f)))
- (make-op (lambda (g)
- (g:- (op g)
- (g:compose h g)))
- `(- ,(operator-name op) ,(procedure-expression h))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op))))
- (define (o:f-o f op)
- (let ((h (coerce-to-function f)))
- (make-op (lambda (g)
- (g:- (g:compose h g)
- (op g)))
- `(- ,(procedure-expression h) ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op))))
- (define (o:negate op)
- (make-op (lambda fs
- (g:negate (apply op fs)))
- `(- ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:* op1 op2)
- (let ((subtype
- (operator-merge-subtypes op1 op2)))
- (if (procedure? subtype)
- (subtype op1 op2)
- (make-op (compose op1 op2)
- `(* ,(operator-name op1)
- ,(operator-name op2))
- subtype
- (operator-arity op2)
- (operator-merge-optionals op1 op2)))))
- (define (o:f*o f op)
- (make-op (lambda gs
- (g:* f (apply op gs)))
- `(* ,(procedure-expression
- (coerce-to-function f))
- ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:o*f op f)
- (make-op (lambda gs
- (apply op (map (lambda (g) (g:* f g)) gs)))
- `(* ,(operator-name op)
- ,(procedure-expression
- (coerce-to-function f)))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:o/n op n)
- (make-op (lambda gs
- (g:* (/ 1 n) (apply op gs)))
- `(/ ,(operator-name op) ,n)
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:expt op n)
- (assert (equal? (operator-arity op) *exactly-one*) "o:expt")
- (make-op (iterated op n o:identity)
- `(expt ,(operator-name op) ,n)
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:exp op)
- (assert (equal? (operator-arity op) *exactly-one*) "o:exp")
- (make-op (lambda (g)
- (lambda x
- ;;; FBE
- ;;(g:apply ((series:value exp-series (list op)) g) x)
- (g:apply (g:apply (series:value exp-series (list op)) (list g)) x)
- ))
- `(exp ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:cos op)
- (assert (equal? (operator-arity op) *exactly-one*) "o:cos")
- (make-op (lambda (g)
- (lambda x
- ;;; FBE
- ;;(g:apply ((series:value cos-series (list op)) g) x)
- (g:apply (g:apply (series:value cos-series (list op)) (list g)) x)
- ))
- `(cos ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- (define (o:sin op)
- (assert (equal? (operator-arity op) *exactly-one*) "o:sin")
- (make-op (lambda (g)
- (lambda x
- ;; FBE
- ;;(g:apply ((series:value sin-series (list op)) g) x)
- (g:apply (g:apply (series:value sin-series (list op)) (list g)) x)
- ))
- `(sin ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op)))
- ;;; Optional order argument for exponentiation of operators.
- ;;; (((expn D 2) g) x)
- ;;; = (((exp D)
- ;;; (lambda (eps)
- ;;; (((+ 1 (* (expt eps 2) D) (* 1/2 (expt eps 4) (expt D 2)) ...) g) x))
- ;;; 0)
- ;;; This is (exp (* (expt eps 2) D)) written as a power series in eps.
- (define* (expn op #:optional exponent)
- (assert (operator? op))
- (assert (equal? (operator-arity op) *exactly-one*) "o:expn")
- (if (default-object? exponent)
- (o:exp op)
- (make-op
- (lambda (g)
- (lambda x
- ;; FBE
- (g:apply ;; ((series:inflate (series:value exp-series (list op))
- ;; exponent)
- ;; g)
- (g:apply (series:inflate (series:value exp-series (list op))
- exponent)
- (list g))
- x)))
- `(exp ,(operator-name op))
- (operator-subtype op)
- (operator-arity op)
- (operator-optionals op))))
- (define %kernel-operator-dummy-1
- (begin
- (assign-operation 'type o:type operator?)
- (assign-operation 'type-predicate o:type-predicate operator?)
- (assign-operation 'arity o:arity operator?)
- (assign-operation 'zero-like o:zero-like simple-operator?)
- (assign-operation 'one-like o:one-like operator?)
- (assign-operation 'identity-like o:one-like operator?)
- (assign-operation '+ o:+ operator? operator?)
- (assign-operation '+ o:o+f operator? not-operator?)
- (assign-operation '+ o:f+o not-operator? operator?)
- (assign-operation '- o:- operator? operator?)
- (assign-operation '- o:o-f operator? not-operator?)
- (assign-operation '- o:f-o not-operator? operator?)
- (assign-operation '* o:* operator? operator?)
- (assign-operation '* o:o*f operator? not-operator?)
- (assign-operation '* o:f*o not-operator? operator?)
- (assign-operation '/ o:o/n operator? numerical-quantity?)
- (assign-operation 'negate o:negate operator?)
- (assign-operation 'expt o:expt operator? exact-integer?)
- (assign-operation 'exp o:exp operator?)
- (assign-operation 'sin o:sin operator?)
- (assign-operation 'cos o:cos operator?)))
|