litfun.scm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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. ;;;; Literal function descriptor language.
  21. ;;; This file is case sensitive.
  22. ;;; The descriptors for literal functions look like prefix versions of
  23. ;;; the standard function types. Thus, we want to be able to say:
  24. ;;; (literal-function 'V (-> (X Real Real) Real))
  25. ;;; The base types are the real numbers, designated by "Real". We
  26. ;;; will later extend the system to include complex numbers,
  27. ;;; designated by "Complex".
  28. ;;; Types can be combined in several ways. The cartesian product of
  29. ;;; types is designated by:
  30. ;;; (X <type1> <type2> ...)
  31. ;;; We use this to specify an argument tuple of objects of the given
  32. ;;; types arranged in the given order.
  33. ;;; Similarly, we can specify an up tuple or a down tuple with:
  34. ;;; (UP <type1> <type2> ...)
  35. ;;; (DOWN <type1> <type2> ...)
  36. ;;; We can also specify a uniform tuple of a number of elements of the
  37. ;;; same type using:
  38. ;;; (UP* <type> [n])
  39. ;;; (DOWN* <type> [n])
  40. #|
  41. ;;; So, for example:
  42. (define H
  43. (literal-function 'H
  44. (-> (UP Real (UP* Real 2) (DOWN* Real 2)) Real)))
  45. (show-expression
  46. (((Hamilton-equations H)
  47. (coordinate-tuple (literal-function 'x)
  48. (literal-function 'y))
  49. (momentum-tuple (literal-function 'p_x)
  50. (literal-function 'p_y)))
  51. 't))
  52. (up
  53. 0
  54. (up
  55. (+ ((D x) t)
  56. (* -1
  57. (((partial 2 0) H) (up t (up (x t) (y t)) (down (p_x t) (p_y t))))))
  58. (+ ((D y) t)
  59. (* -1
  60. (((partial 2 1) H) (up t (up (x t) (y t)) (down (p_x t) (p_y t)))))))
  61. (down
  62. (+ ((D p_x) t)
  63. (((partial 1 0) H) (up t (up (x t) (y t)) (down (p_x t) (p_y t)))))
  64. (+ ((D p_y) t)
  65. (((partial 1 1) H) (up t (up (x t) (y t)) (down (p_x t) (p_y t)))))))
  66. |#
  67. ;;; To get started... Type expressions are self-evaluating
  68. (define Real 'Real)
  69. (define (X . types)
  70. (cond ((null? types) (error "Null type argument -- X"))
  71. ((null? (cdr types)) (car types))
  72. (else (cons 'X types))))
  73. (define (UP . types)
  74. (cond ((null? types) (error "Null type argument -- UP"))
  75. ((null? (cdr types)) (car types))
  76. (else (cons 'UP types))))
  77. (define (DOWN . types)
  78. (cond ((null? types) (error "Null type argument -- DOWN"))
  79. ((null? (cdr types)) (car types))
  80. (else (cons 'DOWN types))))
  81. (define (^ type n) ;n = dimension
  82. (apply X (make-list n type)))
  83. (define (starify rest starred unstarred-proc)
  84. (cond ((null? rest) (error "Null type argument" starred))
  85. (else
  86. (let lp ((args rest) (curtype #f) (explicit #f) (types '()))
  87. (cond ((null? args)
  88. (if explicit (apply unstarred-proc types) (cons starred types)))
  89. ((exact-positive-integer? (car args))
  90. (if curtype
  91. (lp (cdr args)
  92. #f
  93. #t
  94. (append types (make-list (fix:- (car args) 1) curtype)))
  95. (error "Bad type arguments" starred rest)))
  96. (else
  97. (lp (cdr args)
  98. (car args)
  99. #f
  100. (append types (list (car args))))))))))
  101. (define (X* . rest)
  102. (starify rest 'X* X))
  103. (define (UP* . rest)
  104. (starify rest 'UP* UP))
  105. (define (DOWN* . rest)
  106. (starify rest 'DOWN* DOWN))
  107. (define (-> domain range)
  108. `(-> ,domain ,range))
  109. (define Any 'Any)
  110. (define* (default-function-type n #:optional type)
  111. (if (= n 1)
  112. '(-> Real Real)
  113. (-> (X* Real n) Real)))
  114. (define (permissive-function-type n)
  115. (-> (X* Any n) Real))
  116. ;;; Some useful types
  117. (define* (Lagrangian #:optional n) ;n = #degrees-of-freedom
  118. (if (default-object? n)
  119. (-> (UP* Real (UP* Real) (UP* Real)) Real)
  120. (-> (UP Real (UP* Real n) (UP* Real n)) Real)))
  121. (define* (Hamiltonian #:optional n) ;n = #degrees-of-freedom
  122. (if (default-object? n)
  123. (-> (UP Real (UP* Real) (DOWN* Real)) Real)
  124. (-> (UP Real (UP* Real n) (DOWN* Real n)) Real)))
  125. #| ;;; For example
  126. (define L (literal-function 'L (Lagrangian)))
  127. (pe (L (->L-state 't 'x 'v)))
  128. (L (up t x v))
  129. (pe ((D L) (->L-state 't 'x 'v)))
  130. (down (((partial 0) L) (up t x v))
  131. (((partial 1) L) (up t x v))
  132. (((partial 2) L) (up t x v)))
  133. (pe (L (->L-state 't (up 'x 'y) (up 'v_x 'v_y))))
  134. (L (up t (up x y) (up v_x v_y)))
  135. (pe ((D L) (->L-state 't (up 'x 'y) (up 'v_x 'v_y))))
  136. (down
  137. (((partial 0) L) (up t (up x y) (up v_x v_y)))
  138. (down (((partial 1 0) L) (up t (up x y) (up v_x v_y)))
  139. (((partial 1 1) L) (up t (up x y) (up v_x v_y))))
  140. (down (((partial 2 0) L) (up t (up x y) (up v_x v_y)))
  141. (((partial 2 1) L) (up t (up x y) (up v_x v_y)))))
  142. (define H (literal-function 'H (Hamiltonian)))
  143. (pe (H (->H-state 't 'x 'p)))
  144. (H (up t x p))
  145. (pe ((D H) (->H-state 't 'x 'p)))
  146. (down (((partial 0) H) (up t x p))
  147. (((partial 1) H) (up t x p))
  148. (((partial 2) H) (up t x p)))
  149. (pe (H (->H-state 't (up 'x 'y) (down 'p_x 'p_y))))
  150. (H (up t (up x y) (down p_x p_y)))
  151. (pe ((D H) (->H-state 't (up 'x 'y) (down 'p_x 'p_y))))
  152. (down
  153. (((partial 0) H) (up t (up x y) (down p_x p_y)))
  154. (down (((partial 1 0) H) (up t (up x y) (down p_x p_y)))
  155. (((partial 1 1) H) (up t (up x y) (down p_x p_y))))
  156. (up (((partial 2 0) H) (up t (up x y) (down p_x p_y)))
  157. (((partial 2 1) H) (up t (up x y) (down p_x p_y)))))
  158. |#
  159. ;;;---------------------------------------------------------------------
  160. (define (type->domain type)
  161. (assert (eq? (car type) '->))
  162. (cadr type))
  163. (define (type->range-type type)
  164. (assert (eq? (car type) '->))
  165. (caddr type))
  166. (define (type->domain-types type)
  167. (assert (eq? (car type) '->))
  168. (let ((domain (type->domain type)))
  169. (cond ((and (pair? domain) (eq? (car domain) 'X))
  170. (cdr domain))
  171. (else
  172. (list domain)))))
  173. (define (type->arity type)
  174. (assert (eq? (car type) '->))
  175. (let ((domain (type->domain type)))
  176. (cond ((and (pair? domain) (eq? (car domain) 'X))
  177. (length->exact-arity (length (cdr domain))))
  178. ((and (pair? domain) (eq? (car domain) 'X*))
  179. *at-least-zero*)
  180. (else
  181. (length->exact-arity 1)))))
  182. (define (length->exact-arity n)
  183. (assert (exact-integer? n))
  184. (cons n n))
  185. (define (type-expression->predicate type-expression)
  186. (cond ((pair? type-expression)
  187. (case (car type-expression)
  188. ((X)
  189. (let ((type-predicates
  190. (map type-expression->predicate
  191. (cdr type-expression))))
  192. (lambda (datum)
  193. (and (vector? datum)
  194. (all-satisfied type-predicates datum)))))
  195. ((UP)
  196. (let ((type-predicates
  197. (map type-expression->predicate
  198. (cdr type-expression))))
  199. (lambda (datum)
  200. (and (up? datum)
  201. (all-satisfied type-predicates datum)))))
  202. ((DOWN)
  203. (let ((type-predicates
  204. (map type-expression->predicate
  205. (cdr type-expression))))
  206. (lambda (datum)
  207. (and (down? datum)
  208. (all-satisfied type-predicates datum)))))
  209. ((X*)
  210. (let ((type-predicates
  211. (map type-expression->predicate
  212. (cdr type-expression))))
  213. (lambda (datum)
  214. (cond ((vector? datum)
  215. (let ((n (vector-length datum)))
  216. (let lp ((i 0) (preds type-predicates))
  217. (cond ((fix:= i n) #t)
  218. (((car preds) (vector-ref datum i))
  219. (lp (fix:+ i 1)
  220. (if (null? (cdr preds))
  221. preds
  222. (cdr preds))))
  223. (else #f)))))
  224. ((null? (cdr type-predicates))
  225. ((car type-predicates) datum))
  226. (else #f)))))
  227. ((UP* DOWN*)
  228. (let ((type-predicates
  229. (map type-expression->predicate
  230. (cdr type-expression)))
  231. (test?
  232. (if (eq? (car type-expression) 'UP*) up? down?)))
  233. (lambda (datum)
  234. (cond ((test? datum)
  235. (let ((n (s:length datum)))
  236. (let lp ((i 0) (preds type-predicates))
  237. (cond ((fix:= i n) #t)
  238. (((car preds) (s:ref datum i))
  239. (lp (fix:+ i 1)
  240. (if (null? (cdr preds))
  241. preds
  242. (cdr preds))))
  243. (else #f)))))
  244. ((and (not (structure? datum))
  245. (null? (cdr type-predicates)))
  246. ((car type-predicates) datum))
  247. (else #f)))))
  248. ((->) function?)
  249. (else (error "Unknown type combinator" type-expression))))
  250. ((eq? type-expression Real) numerical-quantity?)
  251. ((eq? type-expression Any) any?)
  252. (else (error "Unknown primitive type" type-expression))))
  253. (define (all-satisfied type-preds structure)
  254. (let ((n (length type-preds)))
  255. (and (fix:= n (s:length structure))
  256. (let lp ((types type-preds) (i 0))
  257. (cond ((fix:= i n) #t)
  258. (((car types) (s:ref structure i))
  259. (lp (cdr types) (fix:+ i 1)))
  260. (else #f))))))
  261. (define (type-expression->type-tag type-expression)
  262. (let ((type
  263. (cond ((pair? type-expression)
  264. (case (car type-expression)
  265. ((X) *vector*)
  266. ((UP) *up*)
  267. ((DOWN) *down*)
  268. ((X*) *vector*)
  269. ((UP*) *up*)
  270. ((DOWN*) *down*)
  271. ((->) *function*)
  272. (else
  273. (error "Unknown type combinator" type-expression))))
  274. ((eq? type-expression Real)
  275. *number*)
  276. (else
  277. (error "Unknown primitive type" type-expression)))))
  278. (abstract-type-tag type)))
  279. ;;; For computing the type of the range of the derivative of a
  280. ;;; function with a given type.
  281. (define (df-range-type f-domain-types f-range-type arg)
  282. ;; There is some idea here that I should do something like
  283. ;; (type-complement (type-expression arg) f-range-type)
  284. ;; but the argument currently escapes me as to why I need this.
  285. f-range-type)
  286. ;;; Functions with types are defined as apply hooks...
  287. (define (f:domain-types f)
  288. (if (typed-or-abstract-function? f)
  289. (cadr (apply-hook-extra f))
  290. #f))
  291. (define (f:range-type f)
  292. (if (typed-or-abstract-function? f)
  293. (caddr (apply-hook-extra f))
  294. #f))
  295. ;;; FBE: make it a parameter
  296. ;; (define *literal-reconstruction* #f)
  297. (define *literal-reconstruction* (make-parameter #f))
  298. (define (f:expression f)
  299. (if (typed-or-abstract-function? f)
  300. (if (*literal-reconstruction*)
  301. (cadddr (cdr (apply-hook-extra f)))
  302. (cadddr (apply-hook-extra f)))
  303. #f))
  304. (define (typed-function function range-type domain-types)
  305. (let ((arity (g:arity function)))
  306. (assert (exactly-n? arity)
  307. "I cannot handle this arity -- TYPED-FUNCTION")
  308. (assert (fix:= (length domain-types) (car arity))
  309. "Inconsistent arity -- TYPED-FUNCTION")
  310. (let ((apply-hook (make-apply-hook #f #f)))
  311. (set-apply-hook-procedure! apply-hook function)
  312. (set-apply-hook-extra! apply-hook
  313. (list '*function* domain-types range-type #f))
  314. apply-hook)))
  315. (define (literal-function? f)
  316. (and (apply-hook? f)
  317. (eq? (car (apply-hook-extra f)) '*function*)))
  318. (define* (literal-function fexp #:optional descriptor)
  319. (if (default-object? descriptor)
  320. (set! descriptor (default-function-type 1)))
  321. (let ((arity (type->arity descriptor))
  322. (range-type (type->range-type descriptor)))
  323. (cond ((or (eq? Real range-type)
  324. (eq? '*function* (type-expression->type-tag range-type)))
  325. (litfun fexp arity range-type (type->domain-types descriptor)
  326. `(literal-function ',fexp ,descriptor)))
  327. ((not (symbol? fexp))
  328. (error "Cannot handle this function expression: LITERAL-FUNCTION"
  329. fexp
  330. descriptor))
  331. ((eq? (car range-type) 'UP)
  332. (let ((n (length (cdr range-type))))
  333. (s:generate n 'up
  334. (lambda (i)
  335. (literal-function (symbol fexp '^ i)
  336. (-> (type->domain descriptor)
  337. (list-ref (cdr range-type) i)))))))
  338. ((eq? (car range-type) 'DOWN)
  339. (let ((n (length (cdr range-type))))
  340. (s:generate n 'down
  341. (lambda (i)
  342. (literal-function (symbol fexp '_ i)
  343. (-> (type->domain descriptor)
  344. (list-ref (cdr range-type) i)))))))
  345. (else
  346. (error "Cannot handle this range type: LITERAL-FUNCTION"
  347. fexp
  348. descriptor)))))
  349. (define (litfun fexp arity range-type domain-types call)
  350. ;;(assert (exactly-n? arity)
  351. ;; "I cannot handle this arity -- LITERAL-FUNCTION")
  352. (let ((apply-hook (make-apply-hook #f #f)))
  353. (let ((litf
  354. (cond ((equal? arity *exactly-zero*)
  355. (lambda () (literal-apply apply-hook '())))
  356. ((equal? arity *exactly-one*)
  357. (lambda (x) (literal-apply apply-hook (list x))))
  358. ((equal? arity *exactly-two*)
  359. (lambda (x y) (literal-apply apply-hook (list x y))))
  360. ((equal? arity *exactly-three*)
  361. (lambda (x y z) (literal-apply apply-hook (list x y z))))
  362. (else
  363. (lambda args (literal-apply apply-hook args))))))
  364. (set-apply-hook-procedure! apply-hook litf)
  365. (set-apply-hook-extra! apply-hook
  366. (list '*function* domain-types range-type fexp call))
  367. apply-hook)))
  368. (define (literal-apply apply-hook args)
  369. (if (rexists differential? args)
  370. (litderiv apply-hook args)
  371. (let ((fexp (f:expression apply-hook))
  372. (dtypes (f:domain-types apply-hook))
  373. (rtype (f:range-type apply-hook)))
  374. (let ((dpreds (map type-expression->predicate dtypes))
  375. (range-tag (type-expression->type-tag rtype)))
  376. (assert (&and (map (lambda (p x) (p x)) dpreds args))
  377. "Wrong type argument -- LITERAL-FUNCTION"
  378. (cons fexp args))
  379. (if (eq? range-tag '*function*)
  380. (let ((ans (literal-function `(,fexp ,@args) rtype)))
  381. ;; properties?
  382. ans)
  383. (let ((ans (make-combination range-tag fexp args)))
  384. (add-property! ans 'literal-function apply-hook)
  385. (add-property! ans 'type-expression rtype)
  386. ans))))))
  387. (define (litderiv apply-hook args)
  388. (let ((v (list->up-structure args)))
  389. (let ((maxtag (apply max-order-tag (s:fringe v))))
  390. (let ((ev
  391. (up-structure->list
  392. (s:map/r (lambda (x) (without-tag x maxtag)) v)))
  393. (dv
  394. (s:map/r (lambda (x) (with-tag x maxtag)) v)))
  395. (d:+ (apply apply-hook ev)
  396. (a-reduce d:+
  397. (map (lambda (partialx dx)
  398. (d:* (apply partialx ev) dx))
  399. (s:fringe (make-partials apply-hook v))
  400. (s:fringe dv))))))))
  401. (define (make-partials apply-hook v)
  402. (define (fd indices vv)
  403. (cond ((structure? vv)
  404. (s:generate (s:length vv) (s:same vv)
  405. (lambda (i)
  406. (fd (cons i indices)
  407. (s:ref vv i)))))
  408. ((or (numerical-quantity? vv)
  409. (abstract-quantity? vv))
  410. (let ((fexp
  411. (let ((is (reverse indices)))
  412. (if (equal? (g:arity apply-hook) *exactly-one*) ;univariate
  413. (if (fix:= (car is) 0)
  414. (if (fix:= (length indices) 1)
  415. (symb:derivative (f:expression apply-hook))
  416. `((partial ,@(cdr is))
  417. ,(f:expression apply-hook)))
  418. (error "Wrong indices -- MAKE-PARTIALS"
  419. indices vv))
  420. `((partial ,@is)
  421. ,(f:expression apply-hook)))))
  422. (range
  423. (df-range-type (f:domain-types apply-hook)
  424. (f:range-type apply-hook)
  425. vv))
  426. (domain
  427. (f:domain-types apply-hook)))
  428. (litfun fexp
  429. (g:arity apply-hook)
  430. range
  431. domain
  432. `(literal-function ',fexp
  433. (-> ,(apply X domain) ,range)))))
  434. (else
  435. (error "Bad structure -- MAKE-PARTIALS"
  436. indices vv))))
  437. (fd '() v))
  438. #|
  439. ;;; Not used anywhere.
  440. (define (accumulate-tags v)
  441. (cond ((structure? v)
  442. (let ((n (s:length v)))
  443. (let lp ((i 0) (ut '()))
  444. (if (fix:= i n)
  445. ut
  446. (lp (fix:+ i 1)
  447. (union-differential-tags
  448. ut
  449. (accumulate-tags (s:ref v i))))))))
  450. ((numerical-quantity? v)
  451. (differential-tags
  452. (car (last-pair (differential->terms v)))))
  453. (else
  454. (error "Bad structure -- ACCUMULATE-TAGS" v))))
  455. |#