rules.scm 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  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. ;;;; Rule systems for simplification.
  21. ;;; Written by GJS in the 1980s, edited by Mira Wilczek in summer 2002.
  22. ;;; Edited for a new version in january 2005.
  23. (declare (usual-integrations))
  24. ;;; Default is simplifier lives dangerously.
  25. ;;; allows (log (exp x)) => x
  26. ;;; can confuse x=(x0+n*2pi)i with x0
  27. ;; FBE: make a parameter
  28. (define log-exp-simplify? (make-parameter true))
  29. ;;; If x is real then (sqrt (square x)) = (abs x)
  30. ;;; This is hard to work with, but we usually want to
  31. ;;; allow (sqrt (square x)) => x, but this is
  32. ;;; not necessarily good if x is negative.
  33. (define sqrt-expt-simplify? (make-parameter true))
  34. ;;; If x, y are real non-negative then
  35. ;;; (* (sqrt x) (sqrt y)) = (sqrt (* x y))
  36. ;;; but this is not true for negative factors.
  37. (define sqrt-factor-simplify? (make-parameter true))
  38. ;;; allows (atan y x) => (atan (/ y d) (/ x d)) where d=(gcd x y)
  39. ;;; OK if d is a number (gcd is always positive) but may
  40. ;;; lose quadrant if gcd can be negative for some values of
  41. ;;; its variables.
  42. (define aggressive-atan-simplify? (make-parameter true))
  43. ;;; allows (asin (sin x)) => x, etc
  44. ;;; loses multivalue info, as in log-exp
  45. (define inverse-simplify? (make-parameter true))
  46. ;;; Allows reduction of sin, cos of rational multiples of :pi
  47. (define sin-cos-simplify? (make-parameter true))
  48. ;;; Allow half-angle reductions. Sign of result is hairy!
  49. (define half-angle-simplify? (make-parameter true))
  50. ;;; wierd case: ((d magnitude) (square x)) => 1
  51. (define ignore-zero? (make-parameter true))
  52. ;;; allows commutation of partial derivatives.
  53. ;;; only ok if components selected by partials are unstructured
  54. ;;; (e.g. real)
  55. (define commute-partials? (make-parameter true))
  56. ;;; allows division through by numbers
  57. ;;; e.g. (/ (+ (* 4 x) 5) 3) => (+ (* 4/3 x) 5/3)
  58. (define divide-numbers-through-simplify? (make-parameter true))
  59. ;;; Transforms products of trig functions into functions of sums
  60. ;;; of angles
  61. ;;; e.g. (* (sin x) (cos y))
  62. ;;; ==> (+ (* 1/2 (sin (+ x y))) (* 1/2 (sin (+ x (* -1 y)))) )
  63. (define trig-product-to-sum-simplify? (make-parameter false))
  64. ;;; however, we have control over the defaults
  65. (define (log-exp-simplify doit?)
  66. (assert (boolean? doit?) "argument must be a boolean.")
  67. (clear-memoizer-tables)
  68. (log-exp-simplify? doit?))
  69. (define (sqrt-expt-simplify doit?)
  70. (assert (boolean? doit?) "argument must be a boolean.")
  71. (clear-memoizer-tables)
  72. (sqrt-expt-simplify? doit?))
  73. (define (sqrt-factor-simplify doit?)
  74. (assert (boolean? doit?) "argument must be a boolean.")
  75. (clear-memoizer-tables)
  76. (sqrt-factor-simplify? doit?))
  77. (define (aggressive-atan-simplify doit?)
  78. (assert (boolean? doit?) "argument must be a boolean.")
  79. (clear-memoizer-tables)
  80. (aggressive-atan-simplify? doit?))
  81. (define (inverse-simplify doit?)
  82. (assert (boolean? doit?) "argument must be a boolean.")
  83. (clear-memoizer-tables)
  84. (inverse-simplify? doit?))
  85. (define (sin-cos-simplify doit?)
  86. (assert (boolean? doit?) "argument must be a boolean.")
  87. (clear-memoizer-tables)
  88. (sin-cos-simplify? doit?))
  89. (define (half-angle-simplify doit?)
  90. (assert (boolean? doit?) "argument must be a boolean.")
  91. (clear-memoizer-tables)
  92. (half-angle-simplify? doit?))
  93. (define (ignore-zero-simplify doit?)
  94. (assert (boolean? doit?) "argument must be a boolean.")
  95. (clear-memoizer-tables)
  96. (ignore-zero? doit?))
  97. (define (commute-partials-simplify doit?)
  98. (assert (boolean? doit?) "argument must be a boolean.")
  99. (clear-memoizer-tables)
  100. (commute-partials? doit?))
  101. (define (divide-numbers-through-simplify doit?)
  102. (assert (boolean? doit?) "argument must be a boolean.")
  103. (clear-memoizer-tables)
  104. (divide-numbers-through-simplify? doit?))
  105. (define (trig-product-to-sum-simplify doit?)
  106. (assert (boolean? doit?) "argument must be a boolean.")
  107. (clear-memoizer-tables)
  108. (trig-product-to-sum-simplify? doit?))
  109. ;;; The following predicates are used in trig rules.
  110. (define (negative-number? x)
  111. (and (number? x) (real? x) (negative? x)))
  112. (define (complex-number? z)
  113. (and (complex? z)
  114. (not (n:zero? (n:real-part z)))
  115. (not (n:zero? (n:imag-part z)))))
  116. (define (imaginary-number? z)
  117. (and (complex? z)
  118. (not (n:zero? z))
  119. (n:zero? (n:real-part z))))
  120. (define (imaginary-integer? z)
  121. (and (complex? z)
  122. (not (n:zero? z))
  123. (n:zero? (n:real-part z))
  124. (exact-integer? (n:imag-part z))))
  125. (define (non-integer? x)
  126. (not (integer? x)))
  127. (define (even-integer? x)
  128. (and (integer? x) (even? x) (fix:> x 1)))
  129. (define (odd-integer? x)
  130. (and (integer? x) (odd? x) (fix:> x 1)))
  131. (define (universal-reductions exp)
  132. (let ((vars (variables-in exp)))
  133. (let ((logexp? (occurs-in? '(log exp) vars))
  134. (sincos? (occurs-in? '(sin cos) vars))
  135. (invtrig? (occurs-in? '(asin acos atan) vars))
  136. (sqrt? (memq 'sqrt vars))
  137. (mag? (memq 'magnitude vars))
  138. )
  139. (let* ((e0 (miscsimp exp))
  140. (e1 (if logexp? (logexp e0) e0))
  141. (e2 (if mag? (magsimp e1) e1))
  142. (e3 (if
  143. (and sincos? (symbol? :pi) (sin-cos-simplify?))
  144. (special-trig e2)
  145. e2)))
  146. (cond ((and sincos? invtrig?)
  147. (simsqrt (triginv e3)))
  148. (sqrt? (simsqrt e3))
  149. (else e3))))))
  150. (define logexp
  151. (rule-system
  152. ( (exp (* (? n integer?) (log (? x))))
  153. none
  154. (expt (: x) (: n)) )
  155. ( (exp (log (? x))) none (: x) )
  156. ( (log (exp (? x)))
  157. (and (log-exp-simplify?)
  158. (let ((xs (rcf:simplify x)))
  159. (assume! `(= (exp (log ,xs)) ,xs) 'logexp1)))
  160. (: x) )
  161. ( (sqrt (exp (? x)))
  162. (and (sqrt-expt-simplify?)
  163. (let ((xs (rcf:simplify x)))
  164. (assume! `(= (sqrt (exp ,xs)) (exp (/ ,xs 2)))
  165. 'logexp2)))
  166. (exp (/ (: x) 2)) )
  167. ( (log (sqrt (? x)))
  168. none
  169. (* 1/2 (log (: x))) )
  170. ))
  171. (define magsimp
  172. (rule-system
  173. ( (magnitude (* (? x) (? y) (?? ys)))
  174. none
  175. (* (magnitude (: x)) (magnitude (* (: y) (:: ys)))) )
  176. ( (magnitude (expt (? x) (? n even-integer?)))
  177. none
  178. (expt (: x) (: n)) )
  179. ;; where does this nonsense come from?
  180. ( ((derivative magnitude) (expt (? x) (? n even-integer?)))
  181. (lambda (x)
  182. (error "Who ordered this?" x)
  183. (ignore-zero?))
  184. 1 )
  185. ))
  186. (define miscsimp
  187. (rule-system
  188. ( (expt (? x) 0) none 1 )
  189. ( (expt (? x) 1) none (: x) )
  190. ( (expt (? x) 1/2)
  191. none
  192. (sqrt (: x)) )
  193. ( (expt (expt (? x) (? p/q)) (? m*q))
  194. (integer? (rcf:simplify (symb:* p/q m*q)))
  195. (expt (: x) (: (symb:* p/q m*q))) )
  196. ( (* (?? fs1) ; a rare, expensive luxury
  197. (expt (? x) (? y1))
  198. (?? fs2)
  199. (expt (? x) (? y2))
  200. (?? fs3))
  201. none
  202. (* (:: fs1)
  203. (expt (: x) (+ (: y1) (: y2)))
  204. (:: fs2)
  205. (:: fs3)) )
  206. ))
  207. (define simsqrt
  208. (rule-system
  209. ( (expt (sqrt (? x)) (? n even-integer?))
  210. none
  211. (expt (: x) (: (quotient n 2))) )
  212. ( (sqrt (expt (? x) (? n even-integer?)))
  213. (and (sqrt-expt-simplify?)
  214. (let ((xs (rcf:simplify x)))
  215. (assume! `(= (sqrt (expt ,xs ,n))
  216. (expt ,xs ,(quotient n 2)))
  217. 'simsqrt)))
  218. (expt (: x) (: (quotient n 2))) )
  219. ;; Restrict for |n|>2
  220. ( (sqrt (expt (? x) (? n odd-integer?)))
  221. none
  222. (* (sqrt (: x)) (expt (: x) (: (quotient (fix:- n 1) 2)))) )
  223. ( (expt (sqrt (? x)) (? n odd-integer?))
  224. none
  225. (* (sqrt (: x)) (expt (: x) (: (quotient (fix:- n 1) 2)))) )
  226. ( (/ (? x) (sqrt (? x)))
  227. none
  228. (sqrt (: x)) )
  229. ( (/ (sqrt (? x)) (? x))
  230. none
  231. (/ 1 (sqrt (: x))) )
  232. ( (/ (* (?? u) (? x) (?? v)) (sqrt (? x)))
  233. none
  234. (* (:: u) (sqrt (: x)) (:: v)) )
  235. ( (/ (* (?? u) (sqrt (? x)) (?? v)) (? x))
  236. none
  237. (/ (* (:: u) (:: v)) (sqrt (: x))) )
  238. ( (/ (? x) (* (?? u) (sqrt (? x)) (?? v)))
  239. none
  240. (/ (sqrt (: x)) (* (:: u) (:: v))) )
  241. ( (/ (sqrt (? x)) (* (?? u) (? x) (?? v)))
  242. none
  243. (/ 1 (* (:: u) (sqrt (: x)) (:: v))) )
  244. ( (/ (* (?? p) (? x) (?? q))
  245. (* (?? u) (sqrt (? x)) (?? v)))
  246. none
  247. (/ (* (:: p) (sqrt (: x)) (:: q))
  248. (* (:: u) (:: v))) )
  249. ( (/ (* (?? p) (sqrt (? x)) (?? q))
  250. (* (?? u) (? x) (?? v)))
  251. none
  252. (/ (* (:: p) (:: q))
  253. (* (:: u) (sqrt (: x)) (:: v))) )
  254. ))
  255. (define (non-negative-factors x y id)
  256. (let ((xs (rcf:simplify x))
  257. (ys (rcf:simplify y)))
  258. (define (if-false) #f)
  259. (and (assume! `(non-negative? ,xs) id if-false)
  260. (assume! `(non-negative? ,ys) id if-false))))
  261. (define sqrt-expand
  262. (rule-system
  263. ( (sqrt (* (? x) (? y)))
  264. (and (sqrt-factor-simplify?)
  265. (non-negative-factors x y 'e1))
  266. (* (sqrt (: x)) (sqrt (: y))) )
  267. ( (sqrt (* (? x) (? y) (?? ys)))
  268. (and (sqrt-factor-simplify?)
  269. (non-negative-factors x y 'e2))
  270. (* (sqrt (: x)) (sqrt (* (: y) (:: ys)))) )
  271. ( (sqrt (/ (? x) (? y)))
  272. (and (sqrt-factor-simplify?)
  273. (non-negative-factors x y 'e3))
  274. (/ (sqrt (: x)) (sqrt (: y))) )
  275. ( (sqrt (/ (? x) (? y) (?? ys)))
  276. (and (sqrt-factor-simplify?)
  277. (non-negative-factors x y 'e4))
  278. (/ (sqrt (: x)) (sqrt (* (: y) (:: ys)))) )
  279. ))
  280. (define sqrt-contract
  281. (rule-system
  282. ( (* (?? a) (sqrt (? x)) (?? b) (sqrt (? y)) (?? c))
  283. (and (sqrt-factor-simplify?)
  284. (let ((xs (rcf:simplify x)) (ys (rcf:simplify y)))
  285. (define (if-false) #f)
  286. (if (equal? xs ys)
  287. (and (assume! `(non-negative? ,xs) 'c1 if-false)
  288. `(* ,@a ,xs ,@b ,@c))
  289. (and (assume! `(non-negative? ,xs) 'c1 if-false)
  290. (assume! `(non-negative? ,ys) 'c1 if-false)
  291. `(* ,@a ,@b ,@c (sqrt (* ,xs ,ys))))))) )
  292. ( (/ (sqrt (? x)) (sqrt (? y)))
  293. (and (sqrt-factor-simplify?)
  294. (let ((xs (rcf:simplify x)) (ys (rcf:simplify y)))
  295. (define (if-false) #f)
  296. (if (equal? xs ys)
  297. (and (assume! `(non-negative? ,xs) 'c2 if-false)
  298. 1)
  299. (and (assume! `(non-negative? ,xs) 'c2 if-false)
  300. (assume! `(non-negative? ,ys) 'c2 if-false)
  301. `(sqrt (/ ,xs ,ys)))))) )
  302. ( (/ (* (?? a) (sqrt (? x)) (?? b)) (sqrt (? y)))
  303. (and (sqrt-factor-simplify?)
  304. (let ((xs (rcf:simplify x)) (ys (rcf:simplify y)))
  305. (define (if-false) #f)
  306. (if (equal? xs ys)
  307. (and (assume! `(non-negative? ,xs) 'c3 if-false)
  308. `(* ,@a ,@b))
  309. (and (assume! `(non-negative? ,xs) 'c3 if-false)
  310. (assume! `(non-negative? ,ys) 'c3 if-false)
  311. `(* ,@a ,@b (sqrt (/ ,xs ,ys))))))) )
  312. ( (/ (sqrt (? x)) (* (?? a) (sqrt (? y)) (?? b)))
  313. (and (sqrt-factor-simplify?)
  314. (let ((xs (rcf:simplify x)) (ys (rcf:simplify y)))
  315. (define (if-false) #f)
  316. (if (equal? xs ys)
  317. (and (assume! `(non-negative? ,xs) 'c4 if-false)
  318. `(/ 1 (* ,@a ,@b)))
  319. (and (assume! `(non-negative? ,xs) 'c4 if-false)
  320. (assume! `(non-negative? ,ys) 'c4 if-false)
  321. `(/ (sqrt (/ ,xs ,ys)) (* ,@a ,@b)))))) )
  322. ( (/ (* (?? a) (sqrt (? x)) (?? b))
  323. (* (?? c) (sqrt (? y)) (?? d)))
  324. (and (sqrt-factor-simplify?)
  325. (let ((xs (rcf:simplify x)) (ys (rcf:simplify y)))
  326. (define (if-false) #f)
  327. (if (equal? xs ys)
  328. (and (assume! `(non-negative? ,xs) 'c5 if-false)
  329. `(/ (* ,@a ,@b) (* ,@c ,@d)))
  330. (and (assume! `(non-negative? ,xs) 'c5 if-false)
  331. (assume! `(non-negative? ,ys) 'c5 if-false)
  332. `(/ (* ,@a ,@b (sqrt (/ ,xs ,ys))) (* ,@c ,@d)))))) )
  333. ))
  334. (define specfun->logexp
  335. (rule-system
  336. ( (sqrt (? x)) none (exp (* 1/2 (log (: x)))) )
  337. ( (atan (? z))
  338. none
  339. (/ (- (log (+ 1 (* +i (: z)))) (log (- 1 (* +i (: z))))) +2i) )
  340. ( (asin (? z))
  341. none
  342. (* -i (log (+ (* +i (: z)) (sqrt (- 1 (expt (: z) 2)))))) )
  343. ( (acos (? z))
  344. none
  345. (* -i (log (+ (: z) (* +i (sqrt (- 1 (expt (: z) 2))))))) )
  346. ( (sinh (? u)) none (/ (- (exp (: u)) (exp (* -1 (: u)))) 2) )
  347. ( (cosh (? u)) none (/ (+ (exp (: u)) (exp (* -1 (: u)))) 2) )
  348. ( (expt (? x) (? y non-integer?)) none (exp (* (: y) (log (: x)))) )
  349. ))
  350. (define logexp->specfun
  351. (rule-system
  352. ( (exp (* -1 (log (? x)))) none (expt (: x) -1) )
  353. ( (exp (* 1/2 (log (? x1)))) none (sqrt (: x1)) )
  354. ( (exp (* -1/2 (log (? x1)))) none (/ 1 (sqrt (: x1))) )
  355. ( (exp (* 3/2 (log (? x1)))) none (expt (sqrt (: x1)) 3) )
  356. ( (exp (* -3/2 (log (? x1)))) none (expt (sqrt (: x1)) -3) )
  357. ( (exp (* (?? n1) (log (? x)) (?? n2)))
  358. none
  359. (expt (: x) (* (:: n1) (:: n2))) )
  360. ))
  361. (define log-contract
  362. (rule-system
  363. ( (+ (?? x1) (log (? x2)) (?? x3) (log (? x4)) (?? x5))
  364. none
  365. (+ (:: x1) (:: x3) (:: x5) (log (* (: x2) (: x4)))) )
  366. ( (* (? n integer?) (?? f1) (log (? x)) (?? f2))
  367. none
  368. (* (:: f1) (log (expt (: x) (: n))) (:: f2)) )
  369. ( (+ (?? x1)
  370. (* (?? f1) (log (? x)) (?? f2))
  371. (?? x2)
  372. (* (?? f3) (log (? y)) (?? f4))
  373. (?? x3))
  374. (let ((s1 (rcf:simplify `(* ,@f1 ,@f2)))
  375. (s2 (rcf:simplify `(* ,@f3 ,@f4))))
  376. (if (exact-zero? (rcf:simplify `(- ,s1 ,s2)))
  377. s1
  378. #f))
  379. (+ (* (log (* (: x) (: y))) (: predicate-value))
  380. (:: x1)
  381. (:: x2)
  382. (:: x3)) )
  383. ))
  384. (define log-expand
  385. (rule-system
  386. ( (log (* (? x1) (? x2) (?? xs)))
  387. none
  388. (+ (log (: x1)) (log (* (: x2) (:: xs)))) )
  389. ( (log (expt (? x) (? e))) none (* (: e) (log (: x))) )
  390. ))
  391. (define (list< l1 l2)
  392. (cond ((null? l1) (not (null? l2)))
  393. ((null? l2) #f)
  394. ((< (car l1) (car l2)) #t)
  395. ((> (car l1) (car l2)) #f)
  396. (else (list< (cdr l1) (cdr l2)))))
  397. (define reals?
  398. (let ((s (string->symbol "Real")))
  399. (lambda (r) (eq? r s))))
  400. (define canonicalize-partials
  401. (rule-system
  402. ( (((partial (?? i))
  403. ((partial (?? j))
  404. (? f)))
  405. (?? args))
  406. (and (commute-partials?)
  407. (symbol? f)
  408. (list< j i)
  409. (symb:elementary-access? i args)
  410. (symb:elementary-access? j args))
  411. (((partial (:: j))
  412. ((partial (:: i))
  413. (: f)))
  414. (:: args)) )
  415. #|
  416. ( ((partial (?? i))
  417. (literal-function
  418. (quote ((partial (?? j))
  419. (literal-function (quote (? f))
  420. (-> (? fsjd) (? fsjr reals?)))))
  421. (-> (? fsid) (? fsir reals?))))
  422. (and commute-partials? (list< j i))
  423. ( (partial (:: j))
  424. (literal-function
  425. (quote ((partial (:: i))
  426. (literal-function (quote (: f))
  427. (-> (: fsid) (: fsir)))))
  428. (-> (: fsjd) (: fsjr))) ))
  429. |#
  430. ))
  431. ;;;; trigonometry
  432. ;;; the following rules are used to convert all trig expressions to
  433. ;;; ones involving only sin and cos functions, and to make 1-arg atan
  434. ;;; into 2-arg atan.
  435. (define trig->sincos
  436. (rule-system
  437. ( (tan (? x)) none (/ (sin (: x)) (cos (: x))) )
  438. ( (cot (? x)) none (/ (cos (: x)) (sin (: x))) )
  439. ( (sec (? x)) none (/ 1 (cos (: x))) )
  440. ( (csc (? x)) none (/ 1 (sin (: x))) )
  441. ( (atan (/ (? y) (? x))) none (atan (: y) (: x)) )
  442. ( (atan (? y)) none (atan (: y) 1) )
  443. ))
  444. ;;; sometimes we want to express combinations of sin and cos in terms
  445. ;;; of other functions.
  446. (define sincos->trig
  447. (rule-system
  448. ( (/ (sin (? x)) (cos (? x))) none (tan (: x)) )
  449. ( (/ (* (?? n1) (sin (? x)) (?? n2)) (cos (? x)))
  450. none
  451. (* (:: n1) (tan (: x)) (:: n2)) )
  452. ( (/ (sin (? x)) (* (?? d1) (cos (? x)) (?? d2)))
  453. none
  454. (/ (tan (: x)) (* (:: d1) (:: d2))) )
  455. ( (/ (* (?? n1) (sin (? x)) (?? n2))
  456. (* (?? d1) (cos (? x)) (?? d2)))
  457. none
  458. (/ (* (:: n1) (tan (: x)) (:: n2))
  459. (* (:: d1) (:: d2))) )
  460. ; ( (/ (cos (? x)) (sin (? x))) none (cot (: x)) )
  461. ; ( (/ (* (?? n1) (cos (? x)) (?? n2)) (sin (? x)))
  462. ; none
  463. ; (* (:: n1) (cot (: x)) (:: n2)) )
  464. ; ( (/ (cos (? x)) (* (?? d1) (sin (? x)) (?? d2)))
  465. ; none
  466. ; (/ (cot (: x)) (* (:: d1) (:: d2))) )
  467. ; ( (/ (* (?? n1) (cos (? x)) (?? n2))
  468. ; (* (?? d1) (sin (? x)) (?? d2)))
  469. ; none
  470. ; (/ (* (:: n1) (cot (: x)) (:: n2))
  471. ; (* (:: d1) (:: d2))) )
  472. ))
  473. (define triginv
  474. (rule-system
  475. ( (atan (? y) (? x))
  476. (and (aggressive-atan-simplify?)
  477. (let ((ys (rcf:simplify y)) (xs (rcf:simplify x)))
  478. (if (equal? ys xs)
  479. (if (number? ys)
  480. (if (negative? ys)
  481. '(- (/ (* 3 :pi) 4))
  482. '(/ :pi 4))
  483. (let ((note `(assuming (positive? ,xs))))
  484. (eq-adjoin! note 'rules 'aggressive-atan-1)
  485. (note-that! note)
  486. '(/ :pi 4)))
  487. (if (and (number? ys) (number? xs))
  488. (atan ys xs)
  489. (let ((s (rcf:simplify `(gcd ,ys ,xs))))
  490. (if (equal? s 1)
  491. #f ;do nothing
  492. (let ((note `(assuming (positive? ,s)))
  493. (yv (rcf:simplify `(/ ,ys ,s)))
  494. (xv (rcf:simplify `(/ ,xs ,s))))
  495. (eq-adjoin! note 'rules 'aggressive-atan-2)
  496. (note-that! note)
  497. `(atan ,yv ,xv)))))))) )
  498. ( (sin (asin (? x))) none (: x) )
  499. ( (asin (sin (? x)))
  500. (and (inverse-simplify?)
  501. (let ((xs (rcf:simplify x)))
  502. (assume! `(= (asin (sin ,xs)) ,xs) 'asin-sin)))
  503. (: x) )
  504. ( (cos (acos (? x))) none (: x) )
  505. ( (acos (cos (? x)))
  506. (and (inverse-simplify?)
  507. (let ((xs (rcf:simplify x)))
  508. (assume! `(= (acos (cos ,xs)) ,xs) 'acos-cos)))
  509. (: x) )
  510. ( (tan (atan (? x))) none (: x) )
  511. ( (atan (tan (? x)))
  512. (and (inverse-simplify?)
  513. (let ((xs (rcf:simplify x)))
  514. (assume! `(= (atan (tan ,xs)) ,xs) 'atan-tan)))
  515. (: x) )
  516. ( (sin (acos (? x))) none (sqrt (- 1 (expt (: x) 2))) )
  517. ( (cos (asin (? y))) none (sqrt (- 1 (expt (: y) 2))) )
  518. ( (tan (asin (? y))) none (/ (: y) (sqrt (- 1 (expt (: y) 2)))) )
  519. ( (tan (acos (? x))) none (/ (sqrt (- 1 (expt (: x) 2))) (: x)) )
  520. ( (atan (sin (? x)) (cos (? x)))
  521. (and (inverse-simplify?)
  522. (let ((xs (rcf:simplify x)))
  523. (assume! `(= (atan (sin ,xs) (cos ,xs)) ,xs) `atan-sin-cos)))
  524. (: x) )
  525. ( (asin (cos (? x)))
  526. (and (inverse-simplify?)
  527. (let ((xs (rcf:simplify x)))
  528. (assume! `(= (asin (cos ,xs)) (- (* 1/2 :pi) ,xs)) 'asin-cos)))
  529. (- (* 1/2 :pi) (: x)) )
  530. ( (acos (sin (? x)))
  531. (and (inverse-simplify?)
  532. (let ((xs (rcf:simplify x)))
  533. (assume! `(= (acos (sin ,xs)) (- (* 1/2 :pi) ,xs)) 'acos-sin)))
  534. (- (* 1/2 :pi) (: x)) )
  535. ( (sin (atan (? a) (? b)))
  536. none
  537. (/ (: a) (sqrt (+ (expt (: a) 2) (expt (: b) 2)))) )
  538. ( (cos (atan (? a) (? b)))
  539. none
  540. (/ (: b) (sqrt (+ (expt (: a) 2) (expt (: b) 2)))) )
  541. ))
  542. ;;; Rules when :pi is symbolic.
  543. (define (zero-mod-pi? x)
  544. (integer? (rcf:simplify (symb:/ x :pi))))
  545. (define (pi/2-mod-2pi? x)
  546. (integer?
  547. (rcf:simplify (symb:/ (symb:- x (symb:/ :pi 2)) (symb:* 2 :pi)))))
  548. (define (-pi/2-mod-2pi? x)
  549. (integer?
  550. (rcf:simplify (symb:/ (symb:+ x (symb:/ :pi 2)) (symb:* 2 :pi)))))
  551. (define (pi/2-mod-pi? x)
  552. (integer? (rcf:simplify (symb:/ (symb:- x (symb:/ :pi 2)) :pi))))
  553. (define (zero-mod-2pi? x)
  554. (integer? (rcf:simplify (symb:/ x (symb:* 2 :pi)))))
  555. (define (pi-mod-2pi? x)
  556. (integer? (rcf:simplify (symb:/ (symb:- x :pi) (symb:* 2 :pi)))))
  557. (define (pi/4-mod-pi? x)
  558. (integer? (rcf:simplify (symb:/ (symb:- x (symb:/ :pi 4)) :pi))))
  559. (define (-pi/4-mod-pi? x)
  560. (integer? (rcf:simplify (symb:/ (symb:+ x (symb:/ :pi 4)) :pi))))
  561. (define special-trig
  562. (rule-system
  563. ( (sin (? x zero-mod-pi?)) none 0 )
  564. ( (sin (? x pi/2-mod-2pi?)) none +1 )
  565. ( (sin (? x -pi/2-mod-2pi?)) none -1 )
  566. ( (cos (? x pi/2-mod-pi?)) none 0 )
  567. ( (cos (? x zero-mod-2pi?)) none +1 )
  568. ( (cos (? x pi-mod-2pi?)) none -1 )
  569. ( (tan (? x zero-mod-pi?)) none 0 )
  570. ( (tan (? x pi/4-mod-pi?)) none +1 )
  571. ( (tan (? x -pi/4-mod-pi?)) none -1 )
  572. ))
  573. ;;; sin is odd, and cos is even. we canonicalize by moving the sign
  574. ;;; out of the first term of the argument.
  575. (define angular-parity
  576. (rule-system
  577. ( (cos (? n negative-number?))
  578. none
  579. (cos (: (- n))) )
  580. ( (cos (* (? n negative-number?) (?? x)))
  581. none
  582. (cos (* (: (- n)) (:: x))) )
  583. ( (cos (+ (* (? n negative-number?) (?? x)) (?? y)))
  584. none
  585. (cos (- (* (: (- n)) (:: x)) (:: y))) )
  586. ( (sin (? n negative-number?))
  587. none
  588. (- (sin (: (- n)))) )
  589. ( (sin (* (? n negative-number?) (?? x)))
  590. none
  591. (- (sin (* (: (- n)) (:: x)))) )
  592. ( (sin (+ (* (? n negative-number?) (?? x)) (?? y)))
  593. none
  594. (- (sin (- (* (: (- n)) (:: x)) (:: y)))) )
  595. ))
  596. (define (exact-integer>3? x)
  597. (and (exact-integer? x) (> x 3)))
  598. (define expand-multiangle
  599. (rule-system
  600. ( (sin (* 2 (? x) (?? y)))
  601. none
  602. (* 2 (sin (* (: x) (:: y))) (cos (* (: x) (:: y)))) )
  603. ( (cos (* 2 (? x) (?? y)))
  604. none
  605. (- (* 2 (expt (cos (* (: x) (:: y))) 2)) 1) )
  606. ( (sin (* 3 (? x) (?? y)))
  607. none
  608. (+ (* 3 (sin (* (: x) (:: y)))) (* -4 (expt (sin (* (: x) (:: y))) 3))) )
  609. ( (cos (* 3 (? x) (?? y)))
  610. none
  611. (+ (* 4 (expt (cos (* (: x) (:: y))) 3)) (* -3 (cos (* (: x) (:: y))))) )
  612. ( (sin (* (? n exact-integer>3?) (? f) (?? fs))) ;at least one f
  613. (> n 1)
  614. (+ (* (sin (* (: (- n 1)) (: f) (:: fs))) (cos (* (: f) (:: fs))))
  615. (* (cos (* (: (- n 1)) (: f) (:: fs))) (sin (* (: f) (:: fs))))) )
  616. ( (sin (+ (? x) (? y) (?? ys))) ;at least one y
  617. none
  618. (+ (* (sin (: x)) (cos (+ (: y) (:: ys))))
  619. (* (cos (: x)) (sin (+ (: y) (:: ys))))) )
  620. ( (cos (* (? n exact-integer>3?) (? f) (?? fs))) ;at least one f
  621. (> n 1)
  622. (- (* (cos (* (: (- n 1)) (: f) (:: fs))) (cos (* (: f) (:: fs))))
  623. (* (sin (* (: (- n 1)) (: f) (:: fs))) (sin (* (: f) (:: fs))))) )
  624. ( (cos (+ (? x) (? y) (?? ys))) ;at least one y
  625. none
  626. (- (* (cos (: x)) (cos (+ (: y) (:: ys))))
  627. (* (sin (: x)) (sin (+ (: y) (:: ys))))) )
  628. ))
  629. (define trig-sum-to-product
  630. (rule-system
  631. ( (+ (?? a) (sin (? x)) (?? b) (sin (? y)) (?? c) )
  632. none
  633. (+ (* 2 (sin (/ (+ (: x) (: y)) 2)) (cos (/ (- (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  634. ( (+ (?? a) (sin (? x)) (?? b) (* -1 (sin (? y))) (?? c) )
  635. none
  636. (+ (* 2 (sin (/ (- (: x) (: y)) 2)) (cos (/ (+ (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  637. ( (+ (?? a) (* -1 (sin (? y))) (?? b) (sin (? x)) (?? c) )
  638. none
  639. (+ (* 2 (sin (/ (- (: x) (: y)) 2)) (cos (/ (+ (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  640. ( (+ (?? a) (cos (? x)) (?? b) (cos (? y)) (?? c) )
  641. none
  642. (+ (* 2 (cos (/ (+ (: x) (: y)) 2)) (cos (/ (- (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  643. ( (+ (?? a) (cos (? x)) (?? b) (* -1 (cos (? y))) (?? c) )
  644. none
  645. (+ (* -2 (sin (/ (+ (: x) (: y)) 2)) (sin (/ (- (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  646. ( (+ (?? a) (* -1 (cos (? y))) (?? b) (cos (? x)) (?? c) )
  647. none
  648. (+ (* -2 (sin (/ (+ (: x) (: y)) 2)) (sin (/ (- (: x) (: y)) 2))) (:: a) (:: b) (:: c)) )
  649. ))
  650. (define trig-product-to-sum
  651. (rule-system
  652. ( (* (?? u) (sin (? x)) (?? v) (sin (? y)) (?? w))
  653. none
  654. (* 1/2 (- (cos (- (: x) (: y))) (cos (+ (: x) (: y)))) (:: u) (:: v) (:: w)) )
  655. ( (* (?? u) (cos (? x)) (?? v) (cos (? y)) (?? w))
  656. none
  657. (* 1/2 (+ (cos (- (: x) (: y))) (cos (+ (: x) (: y)))) (:: u) (:: v) (:: w)) )
  658. ( (* (?? u) (sin (? x)) (?? v) (cos (? y)) (?? w))
  659. none
  660. (* 1/2 (+ (sin (+ (: x) (: y))) (sin (- (: x) (: y)))) (:: u) (:: v) (:: w)) )
  661. ( (* (?? u) (cos (? y)) (?? v) (sin (? x)) (?? w))
  662. none
  663. (* 1/2 (+ (sin (+ (: x) (: y))) (sin (- (: x) (: y)))) (:: u) (:: v) (:: w)) )
  664. ))
  665. (define contract-expt-trig
  666. (rule-system
  667. ( (expt (sin (? x)) (? n exact-integer?))
  668. (> n 1)
  669. (* 1/2 (expt (sin (: x)) (: (- n 2))) (- 1 (cos (* 2 (: x))))))
  670. ( (expt (cos (? x)) (? n exact-integer?))
  671. (> n 1)
  672. (* 1/2 (expt (cos (: x)) (: (- n 2))) (+ 1 (cos (* 2 (: x))))))
  673. ))
  674. (define (sin-half-angle-formula theta)
  675. (let ((thetas (rcf:simplify theta)))
  676. (assume!
  677. `(non-negative?
  678. (+ (* 2 :pi)
  679. (* -1 ,thetas)
  680. (* 4 :pi (floor (/ ,thetas (* 4 :pi))))))
  681. 'sin-half-angle-formula)
  682. `(sqrt (/ (- 1 (cos ,thetas)) 2))))
  683. (define (cos-half-angle-formula theta)
  684. (let ((thetas (rcf:simplify theta)))
  685. (assume!
  686. `(non-negative?
  687. (+ :pi
  688. ,thetas
  689. (* 4 :pi
  690. (floor (/ (- :pi ,thetas) (* 4 :pi))))))
  691. 'cos-half-angle-formula)
  692. `(sqrt (/ (+ 1 (cos ,theta)) 2))))
  693. (define half-angle
  694. (rule-system
  695. ( (sin (* 1/2 (? x) (?? y)))
  696. (and (half-angle-simplify?)
  697. (sin-half-angle-formula `(* ,x ,@y))) )
  698. ( (sin (/ (? x) 2))
  699. (and (half-angle-simplify?)
  700. (sin-half-angle-formula x)) )
  701. ( (cos (* 1/2 (? x) (?? y)))
  702. (and (half-angle-simplify?)
  703. (cos-half-angle-formula `(* ,x ,@y))) )
  704. ( (cos (/ (? x) 2))
  705. (and (half-angle-simplify?)
  706. (cos-half-angle-formula x)) )
  707. ))
  708. (define (at-least-two? n)
  709. (and (number? n) (>= n 2)))
  710. (define sin^2->cos^2
  711. (rule-system
  712. ( (expt (sin (? x)) (? n at-least-two?))
  713. none
  714. (* (expt (sin (: x)) (: (- n 2)))
  715. (- 1 (expt (cos (: x)) 2))) )
  716. ))
  717. (define cos^2->sin^2
  718. (rule-system
  719. ( (expt (cos (? x)) (? n at-least-two?))
  720. none
  721. (* (expt (cos (: x)) (: (- n 2)))
  722. (- 1 (expt (sin (: x)) 2))) )
  723. ))
  724. (define (sincos-flush-ones expression)
  725. ;; Order here is essential, to put sines before cosines.
  726. (flush-obvious-ones
  727. (split-high-degree-sines
  728. (split-high-degree-cosines expression))))
  729. (define (more-than-two? n)
  730. (and (number? n) (> n 2)))
  731. (define split-high-degree-cosines
  732. (rule-system
  733. ( (* (?? f1)
  734. (expt (cos (? x)) (? n more-than-two?))
  735. (?? f2))
  736. none
  737. (* (expt (cos (: x)) 2)
  738. (expt (cos (: x)) (: (- n 2)))
  739. (:: f1)
  740. (:: f2)) )
  741. ( (+ (?? a1)
  742. (expt (cos (? x)) (? n more-than-two?))
  743. (?? a2))
  744. none
  745. (+ (* (expt (cos (: x)) 2)
  746. (expt (cos (: x)) (: (- n 2))))
  747. (:: a1)
  748. (:: a2)) )
  749. ))
  750. (define split-high-degree-sines
  751. (rule-system
  752. ( (* (?? f1)
  753. (expt (sin (? x)) (? n more-than-two?))
  754. (?? f2))
  755. none
  756. (* (expt (sin (: x)) 2)
  757. (expt (sin (: x)) (: (- n 2)))
  758. (:: f1)
  759. (:: f2)) )
  760. ( (+ (?? a1)
  761. (expt (sin (? x)) (? n more-than-two?))
  762. (?? a2))
  763. none
  764. (+ (* (expt (sin (: x)) 2)
  765. (expt (sin (: x)) (: (- n 2))))
  766. (:: a1)
  767. (:: a2)) )
  768. ))
  769. (define flush-obvious-ones
  770. (rule-system
  771. ( (+ (?? a1)
  772. (expt (sin (? x)) 2)
  773. (?? a2)
  774. (expt (cos (? x)) 2)
  775. (?? a3))
  776. none
  777. (+ 1 (:: a1) (:: a2) (:: a3)) )
  778. #|;; Sines are before cosines (see note above)
  779. ( (+ (?? a1)
  780. (expt (cos (? x)) 2)
  781. (?? a2)
  782. (expt (sin (? x)) 2)
  783. (?? a3))
  784. none
  785. (+ (:: a1) (:: a2) (:: a3) 1) )
  786. |#
  787. ( (+ (?? a1)
  788. (* (expt (sin (? x)) 2) (?? f1))
  789. (?? a2)
  790. (* (expt (cos (? x)) 2) (?? f2))
  791. (?? a3))
  792. (let ((s1 (rcf:simplify `(* ,@f1)))
  793. (s2 (rcf:simplify `(* ,@f2))))
  794. (if (exact-zero? (rcf:simplify `(- ,s1 ,s2)))
  795. s1
  796. #f))
  797. (+ (:: a1) (:: a2) (:: a3) (: predicate-value)) )
  798. #|;; Sines are before cosines (see note above)
  799. ( (+ (?? a1)
  800. (* (expt (cos (? x)) 2) (?? f1))
  801. (?? a2)
  802. (* (expt (sin (? x)) 2) (?? f2))
  803. (?? a3))
  804. (let ((s1 (rcf:simplify `(* ,@f1)))
  805. (s2 (rcf:simplify `(* ,@f2))))
  806. (if (exact-zero? (rcf:simplify `(- ,s1 ,s2)))
  807. s1
  808. #f))
  809. (+ (:: a1) (:: a2) (:: a3) (: predicate-value)) )
  810. |#
  811. ))
  812. ;;; here are some residual rules.
  813. (define sincos-random
  814. (rule-system
  815. ( (+ (?? a1) (? a) (?? a2) (expt (cos (? x)) (? n at-least-two?)) (?? a3))
  816. (exact-zero? (rcf:simplify `(+ ,a (expt (cos ,x) ,(- n 2)))))
  817. (+ (:: a1) (:: a2) (:: a3) (* (expt (sin (: x)) 2) (: a))) )
  818. ( (+ (?? a1) (expt (cos (? x)) (? n at-least-two?)) (?? a2) (? a) (?? a3))
  819. (exact-zero? (rcf:simplify `(+ ,a (expt (cos ,x) ,(- n 2)))))
  820. (+ (:: a1) (:: a2) (:: a3) (* (expt (sin (: x)) 2) (: a))) )
  821. ( (+ (?? a1) (? a) (?? a2) (expt (sin (? x)) (? n at-least-two?)) (?? a3))
  822. (exact-zero? (rcf:simplify `(+ ,a (expt (sin ,x) ,(- n 2)))))
  823. (+ (:: a1) (:: a2) (:: a3) (* (expt (cos (: x)) 2) (: a))) )
  824. ( (+ (?? a1) (expt (sin (? x)) (? n at-least-two?)) (?? a2) (? a) (?? a3))
  825. (exact-zero? (rcf:simplify `(+ ,a (expt (sin ,x) ,(- n 2)))))
  826. (+ (:: a1) (:: a2) (:: a3) (* (expt (cos (: x)) 2) (: a))) )
  827. ( (+ (?? a1)
  828. (? a)
  829. (?? a2)
  830. (* (?? b1) (expt (cos (? x)) (? n at-least-two?)) (?? b2))
  831. (?? a3))
  832. (exact-zero? (rcf:simplify `(+ (* ,@b1 ,@b2 (expt (cos ,x) ,(- n 2))) ,a)))
  833. (+ (:: a1) (:: a2) (:: a3) (* (: a) (expt (sin (: x)) 2))) )
  834. ( (+ (?? a1)
  835. (? a)
  836. (?? a2)
  837. (* (?? b1) (expt (sin (? x)) (? n at-least-two?)) (?? b2))
  838. (?? a3))
  839. (exact-zero? (rcf:simplify `(+ (* ,@b1 ,@b2 (expt (sin ,x) ,(- n 2))) ,a)))
  840. (+ (:: a1) (:: a2) (:: a3) (* (: a) (expt (cos (: x)) 2))) )
  841. ( (+ (?? a1)
  842. (* (?? b1) (expt (cos (? x)) (? n at-least-two?)) (?? b2))
  843. (?? a2)
  844. (? a)
  845. (?? a3))
  846. (exact-zero? (rcf:simplify `(+ (* ,@b1 ,@b2 (expt (cos ,x) ,(- n 2))) ,a)))
  847. (+ (:: a1) (:: a2) (:: a3) (* (: a) (expt (sin (: x)) 2))) )
  848. ( (+ (?? a1)
  849. (* (?? b1) (expt (sin (? x)) (? n at-least-two?)) (?? b2))
  850. (?? a2)
  851. (? a)
  852. (?? a3))
  853. (exact-zero? (rcf:simplify `(+ (* ,@b1 ,@b2 (expt (sin ,x) ,(- n 2))) ,a)))
  854. (+ (:: a1) (:: a2) (:: a3) (* (: a) (expt (cos (: x)) 2))) )
  855. ))
  856. ;;; we can eliminate sin and cos in favor of complex exponentials
  857. (define sincos->exp1
  858. (rule-system
  859. ( (sin (? x))
  860. none
  861. (/ (- (exp (* +i (: x))) (exp (* -i (: x))))
  862. +2i) )
  863. ( (cos (? x))
  864. none
  865. (/ (+ (exp (* +i (: x))) (exp (* -i (: x))))
  866. 2) )
  867. ))
  868. (define sincos->exp2
  869. (rule-system
  870. ( (sin (? x))
  871. none
  872. (/ (- (exp (* +i (: x))) (/ 1 (exp (* +i (: x)))))
  873. +2i) )
  874. ( (cos (? x))
  875. none
  876. (/ (+ (exp (* +i (: x))) (/ 1 (exp (* +i (: x)))))
  877. 2) )
  878. ))
  879. ;;; under favorable conditions, we can replace the trig functions.
  880. (define exp->sincos
  881. (rule-system
  882. ( (exp (? c1 imaginary-number?))
  883. (positive? (n:imag-part c1))
  884. (+ (cos (: (n:imag-part c1)))
  885. (* +i (sin (: (n:imag-part c1))))) )
  886. ( (exp (? c1 imaginary-number?))
  887. (negative? (n:imag-part c1))
  888. (+ (cos (: (- (n:imag-part c1))))
  889. (* -i (sin (: (- (n:imag-part c1)))))) )
  890. ( (exp (* (? c1 imaginary-number?) (?? f)))
  891. (positive? (n:imag-part c1))
  892. (+ (cos (* (: (n:imag-part c1)) (:: f)))
  893. (* +i (sin (* (: (n:imag-part c1)) (:: f))))) )
  894. ( (exp (* (? c1 imaginary-number?) (?? f)))
  895. (negative? (n:imag-part c1))
  896. (* (exp (: (n:real-part c1)))
  897. (+ (cos (* (: (- (n:imag-part c1))) (:: f)))
  898. (* -i (sin (* (: (- (n:imag-part c1))) (:: f)))))) )
  899. ( (exp (? c1 complex-number?))
  900. (positive? (n:imag-part c1))
  901. (* (exp (: (n:real-part c1)))
  902. (+ (cos (: (n:imag-part c1)))
  903. (* +i (sin (: (n:imag-part c1)))))) )
  904. ( (exp (? c1 complex-number?))
  905. (negative? (n:imag-part c1))
  906. (* (exp (: (n:real-part c1)))
  907. (+ (cos (: (- (n:imag-part c1))))
  908. (* -i (sin (: (- (n:imag-part c1))))))) )
  909. ( (exp (* (? c1 complex-number?) (?? f)))
  910. (positive? (n:imag-part c1))
  911. (* (exp (: (n:real-part c1)))
  912. (+ (cos (* (: (n:imag-part c1)) (:: f)))
  913. (* +i (sin (* (: (n:imag-part c1)) (:: f)))))) )
  914. ( (exp (* (? c1 complex-number?) (?? f)))
  915. (negative? (n:imag-part c1))
  916. (* (exp (: (n:real-part c1)))
  917. (+ (cos (* (: (- (n:imag-part c1))) (:: f)))
  918. (* -i (sin (* (: (- (n:imag-part c1))) (:: f)))))) )
  919. ))
  920. (define exp-contract
  921. (rule-system
  922. ( (* (?? x1) (exp (? x2)) (?? x3) (exp (? x4)) (?? x5))
  923. none
  924. (* (:: x1) (:: x3) (:: x5) (exp (+ (: x2) (: x4)))) )
  925. ( (expt (exp (? x)) (? p)) none (exp (* (: p) (: x))) )
  926. ( (/ (exp (? x)) (exp (? y))) none (exp (- (: x) (: y))) )
  927. ( (/ (* (?? x1) (exp (? x)) (?? x2)) (exp (? y)))
  928. none
  929. (* (:: x1) (:: x2) (exp (- (: x) (: y)))) )
  930. ( (/ (exp (? x)) (* (?? y1) (exp (? y)) (?? y2)))
  931. none
  932. (/ (exp (- (: x) (: y))) (* (:: y1) (:: y2))) )
  933. ( (/ (* (?? x1) (exp (? x)) (?? x2))
  934. (* (?? y1) (exp (? y)) (?? y2)))
  935. none
  936. (/ (* (:: x1) (:: x2) (exp (- (: x) (: y))))
  937. (* (:: y1) (:: y2))) )
  938. ))
  939. (define exp-expand
  940. (rule-system
  941. ( (exp (- (? x1)))
  942. none
  943. (/ 1 (exp (: x1))) )
  944. ( (exp (- (? x1) (? x2)))
  945. none
  946. (/ (exp (: x1)) (exp (: x2))) )
  947. ( (exp (+ (? x1) (? x2) (?? xs)))
  948. none
  949. (* (exp (: x1)) (exp (+ (: x2) (:: xs)))) )
  950. ( (exp (* (? x imaginary-integer?) (?? factors)))
  951. (> (n:imag-part x) 1)
  952. (expt (exp (* +i (:: factors))) (: (n:imag-part x))) )
  953. ( (exp (* (? x imaginary-integer?) (?? factors)))
  954. (< (n:imag-part x) -1)
  955. (expt (exp (* -i (:: factors))) (: (- (n:imag-part x)))) )
  956. ( (exp (* (? n exact-integer?) (?? factors)))
  957. (> n 1)
  958. (expt (exp (* (:: factors))) (: n)) )
  959. ( (exp (* (? n exact-integer?) (?? factors)))
  960. (< n -1)
  961. (expt (exp (* -1 (:: factors))) (: (- n))) )
  962. ( (exp (? x complex-number?))
  963. none
  964. (* (exp (: (n:real-part x)))
  965. (exp (: (n:* (n:imag-part x) +i)))) )
  966. ( (exp (* (? x complex-number?) (?? factors)))
  967. none
  968. (* (exp (* (: (n:real-part x)) (:: factors)))
  969. (exp (* (: (n:* (n:imag-part x) +i)) (:: factors)))) )
  970. ))
  971. (define complex-rules
  972. (rule-system
  973. ( (make-rectangular (cos (? theta)) (sin (? theta)))
  974. none
  975. (exp (* +i (: theta))) )
  976. ( (real-part (make-rectangular (? x) (? y)))
  977. none
  978. (: x) )
  979. ( (imag-part (make-rectangular (? x) (? y)))
  980. none
  981. (: x) )
  982. ( (magnitude (make-rectangular (? x) (? y)))
  983. none
  984. (sqrt (+ (expt (: x) 2) (expt (: y) 2))) )
  985. ( (angle (make-rectangular (? x) (? y)))
  986. none
  987. (atan (: y) (: x)) )
  988. ( (real-part (make-polar (? m) (? a)))
  989. none
  990. (* (: m) (cos (: a))) )
  991. ( (imag-part (make-polar (? m) (? a)))
  992. none
  993. (* (: m) (sin (: a))) )
  994. ( (magnitude (make-polar (? m) (? a)))
  995. none
  996. (: m) )
  997. ( (angle (make-polar (? m) (? a)))
  998. none
  999. (: a) )
  1000. ))
  1001. (define divide-numbers-through
  1002. (rule-system
  1003. ( (* 1 (? factor))
  1004. none
  1005. (: factor) )
  1006. ( (* 1 (?? factors))
  1007. none
  1008. (* (:: factors)) )
  1009. ( (/ (? n number?) (? d number?))
  1010. none
  1011. (: (/ n d)) )
  1012. ( (/ (+ (?? terms)) (? d number?))
  1013. none
  1014. (+ (:: (map (lambda (term) `(/ ,term ,d))
  1015. terms))) )
  1016. ( (/ (* (? n number?) (?? factors)) (? d number?))
  1017. none
  1018. (* (: (/ n d)) (:: factors)) )
  1019. ( (/ (* (?? factors)) (? d number?))
  1020. none
  1021. (* (: (n:invert d)) (:: factors)) )
  1022. ( (/ (? n) (* (? d number?) (? factor)))
  1023. none
  1024. (/ (/ (: n) (: d)) (: factor)) )
  1025. ( (/ (? n) (* (? d number?) (?? factors)))
  1026. none
  1027. (/ (/ (: n) (: d)) (* (:: factors))) )
  1028. ( (/ (? n) (? d number?))
  1029. none
  1030. (* (: (n:invert d)) (: n)) )
  1031. ))
  1032. ;;;; simplifiers defined using these rule sets
  1033. ;;; assuming that expression comes in canonical it goes out canonical
  1034. #|
  1035. (define (simplify-until-stable rule-simplify canonicalize)
  1036. (define (simp exp)
  1037. (let ((newexp (rule-simplify exp)))
  1038. (if (equal? exp newexp)
  1039. exp
  1040. (simp (canonicalize newexp)))))
  1041. simp)
  1042. (define (simplify-until-stable rule-simplify canonicalize)
  1043. (define (simp exp)
  1044. (let ((newexp (rule-simplify exp)))
  1045. (if (equal? exp newexp)
  1046. exp
  1047. (let ((cexp (canonicalize newexp)))
  1048. (if (equal? exp cexp)
  1049. exp
  1050. (simp cexp))))))
  1051. simp)
  1052. |#
  1053. (define (simplify-until-stable rule-simplify canonicalize)
  1054. (define (simp exp)
  1055. (let ((newexp (rule-simplify exp)))
  1056. (if (equal? exp newexp)
  1057. exp
  1058. (let ((cexp (canonicalize newexp)))
  1059. (cond ((equal? cexp exp) exp)
  1060. ((exact-zero? (fpf:simplify `(- ,exp ,cexp))) cexp)
  1061. (else (simp cexp)))))))
  1062. simp)
  1063. ;;; Once around.
  1064. (define (simplify-and-canonicalize rule-simplify canonicalize)
  1065. (define (simp exp)
  1066. (let ((newexp (rule-simplify exp)))
  1067. (if (equal? exp newexp)
  1068. exp
  1069. (canonicalize newexp))))
  1070. simp)
  1071. ;;; the usual canonicalizer is
  1072. (define simplify-and-flatten
  1073. (compose fpf:simplify rcf:simplify))
  1074. (define (only-if p? do)
  1075. (lambda (exp)
  1076. (if (p? exp) (do exp) exp)))
  1077. (define ->poisson-form
  1078. (compose simplify-and-flatten
  1079. angular-parity
  1080. (simplify-until-stable
  1081. (compose trig-product-to-sum simplify-and-flatten contract-expt-trig)
  1082. simplify-and-flatten)
  1083. simplify-and-flatten
  1084. trig->sincos))
  1085. (define (trigexpand exp)
  1086. ((compose simplify-and-flatten
  1087. sincos->trig
  1088. simplify-and-flatten
  1089. sincos-flush-ones
  1090. simplify-and-flatten
  1091. exp->sincos
  1092. (simplify-until-stable exp-expand simplify-and-flatten)
  1093. (simplify-until-stable exp-contract simplify-and-flatten)
  1094. (simplify-until-stable exp-expand simplify-and-flatten)
  1095. simplify-and-flatten
  1096. sincos->exp1
  1097. trig->sincos)
  1098. exp))
  1099. (define (trigcontract exp)
  1100. ((compose simplify-and-flatten
  1101. sincos->trig
  1102. (simplify-until-stable sincos-flush-ones simplify-and-flatten)
  1103. simplify-and-flatten
  1104. exp->sincos
  1105. (simplify-until-stable exp-expand simplify-and-flatten)
  1106. simplify-and-flatten
  1107. sincos-flush-ones
  1108. simplify-and-flatten
  1109. exp->sincos
  1110. (simplify-until-stable exp-contract simplify-and-flatten)
  1111. (simplify-until-stable exp-expand simplify-and-flatten)
  1112. simplify-and-flatten
  1113. sincos->exp1
  1114. trig->sincos)
  1115. exp))
  1116. (define (full-simplify exp)
  1117. ((compose rcf:simplify
  1118. (simplify-until-stable universal-reductions
  1119. rcf:simplify)
  1120. ; (simplify-until-stable sqrt-contract
  1121. ; rcf:simplify)
  1122. (simplify-until-stable sqrt-expand
  1123. rcf:simplify)
  1124. (simplify-until-stable sqrt-contract
  1125. rcf:simplify)
  1126. rcf:simplify
  1127. logexp->specfun
  1128. sincos->trig
  1129. simplify-and-flatten
  1130. sincos-flush-ones
  1131. rcf:simplify
  1132. exp->sincos
  1133. (simplify-until-stable (compose log-expand exp-expand)
  1134. rcf:simplify)
  1135. (simplify-until-stable (compose log-contract exp-contract)
  1136. rcf:simplify)
  1137. (simplify-until-stable (compose log-expand exp-expand)
  1138. rcf:simplify)
  1139. rcf:simplify
  1140. sincos->exp1
  1141. trig->sincos
  1142. specfun->logexp
  1143. (simplify-until-stable (compose universal-reductions sqrt-expand)
  1144. rcf:simplify)
  1145. rcf:simplify
  1146. )
  1147. exp))
  1148. (define (oe-simplify exp)
  1149. ((compose (simplify-until-stable universal-reductions
  1150. simplify-and-flatten)
  1151. (simplify-until-stable sqrt-expand
  1152. simplify-and-flatten)
  1153. (simplify-until-stable sqrt-contract
  1154. simplify-and-flatten)
  1155. simplify-and-flatten
  1156. sincos->trig
  1157. (simplify-until-stable sincos-random
  1158. simplify-and-flatten)
  1159. simplify-and-flatten
  1160. sin^2->cos^2
  1161. simplify-and-flatten
  1162. sincos-flush-ones
  1163. (simplify-until-stable (compose log-expand exp-expand)
  1164. simplify-and-flatten)
  1165. (simplify-until-stable (compose log-contract exp-contract)
  1166. simplify-and-flatten)
  1167. (simplify-until-stable (compose log-expand exp-expand)
  1168. simplify-and-flatten)
  1169. (simplify-until-stable angular-parity
  1170. simplify-and-flatten)
  1171. (simplify-until-stable (compose universal-reductions sqrt-expand)
  1172. simplify-and-flatten)
  1173. simplify-and-flatten
  1174. trig->sincos
  1175. canonicalize-partials
  1176. )
  1177. exp))
  1178. (define (easy-simplify exp)
  1179. ((compose (simplify-until-stable (compose universal-reductions sqrt-expand)
  1180. simplify-and-flatten)
  1181. simplify-and-flatten
  1182. root-out-squares
  1183. (simplify-until-stable sqrt-contract
  1184. simplify-and-flatten)
  1185. sincos->trig
  1186. (simplify-until-stable sincos-random
  1187. simplify-and-flatten)
  1188. simplify-and-flatten
  1189. sin^2->cos^2
  1190. simplify-and-flatten
  1191. sincos-flush-ones
  1192. (simplify-until-stable (compose log-expand exp-expand)
  1193. simplify-and-flatten)
  1194. (simplify-until-stable (compose log-contract exp-contract)
  1195. simplify-and-flatten)
  1196. (simplify-until-stable (compose universal-reductions
  1197. angular-parity
  1198. log-expand
  1199. exp-expand
  1200. sqrt-expand)
  1201. simplify-and-flatten)
  1202. simplify-and-flatten
  1203. trig->sincos
  1204. canonicalize-partials
  1205. )
  1206. exp))
  1207. (define (clear-square-roots-of-perfect-squares expr)
  1208. (if (sqrt-expt-simplify?)
  1209. ((simplify-and-canonicalize (compose universal-reductions
  1210. root-out-squares)
  1211. simplify-and-flatten)
  1212. expr)
  1213. expr))
  1214. (define (new-simplify exp)
  1215. (define (sqrt? exp)
  1216. (occurs-in? '(sqrt) exp))
  1217. (define (full-sqrt? exp)
  1218. (and (sqrt-factor-simplify?)
  1219. (occurs-in? '(sqrt) exp)))
  1220. (define (logexp? exp)
  1221. (occurs-in? '(log exp) exp))
  1222. (define (sincos? exp)
  1223. (occurs-in? '(sin cos) exp))
  1224. (define (partials? exp)
  1225. (occurs-in? '(partial) exp))
  1226. ((compose (only-if (lambda (exp) (divide-numbers-through-simplify?))
  1227. divide-numbers-through)
  1228. (only-if sqrt? clear-square-roots-of-perfect-squares)
  1229. (only-if full-sqrt?
  1230. (compose
  1231. (simplify-until-stable (compose universal-reductions
  1232. sqrt-expand)
  1233. simplify-and-flatten)
  1234. clear-square-roots-of-perfect-squares
  1235. (simplify-until-stable sqrt-contract
  1236. simplify-and-flatten)))
  1237. (only-if sincos?
  1238. (compose (simplify-and-canonicalize
  1239. (compose universal-reductions sincos->trig)
  1240. simplify-and-flatten)
  1241. (simplify-and-canonicalize angular-parity
  1242. simplify-and-flatten)
  1243. (simplify-until-stable sincos-random
  1244. simplify-and-flatten)
  1245. (simplify-and-canonicalize sin^2->cos^2
  1246. simplify-and-flatten)
  1247. (simplify-and-canonicalize sincos-flush-ones
  1248. simplify-and-flatten)
  1249. (if (trig-product-to-sum-simplify?)
  1250. (simplify-and-canonicalize trig-product-to-sum
  1251. simplify-and-flatten)
  1252. (lambda (x) x))
  1253. (simplify-and-canonicalize universal-reductions
  1254. simplify-and-flatten)
  1255. (simplify-until-stable sincos-random
  1256. simplify-and-flatten)
  1257. (simplify-and-canonicalize sin^2->cos^2
  1258. simplify-and-flatten)
  1259. (simplify-and-canonicalize sincos-flush-ones
  1260. simplify-and-flatten)))
  1261. (only-if logexp?
  1262. (compose
  1263. (simplify-and-canonicalize universal-reductions
  1264. simplify-and-flatten)
  1265. (simplify-until-stable (compose log-expand exp-expand)
  1266. simplify-and-flatten)
  1267. (simplify-until-stable (compose log-contract exp-contract)
  1268. simplify-and-flatten)))
  1269. (simplify-until-stable (compose universal-reductions
  1270. (only-if logexp?
  1271. (compose log-expand
  1272. exp-expand))
  1273. (only-if sqrt? sqrt-expand))
  1274. simplify-and-flatten)
  1275. (only-if sincos?
  1276. (simplify-and-canonicalize angular-parity
  1277. simplify-and-flatten))
  1278. (simplify-and-canonicalize trig->sincos simplify-and-flatten)
  1279. (only-if partials?
  1280. (simplify-and-canonicalize canonicalize-partials
  1281. simplify-and-flatten))
  1282. simplify-and-flatten
  1283. )
  1284. exp))