| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | ! Copyright (C) 2008 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2012-04-05 12:17:52 -04:00
										 |  |  | USING: accessors kernel kernel.private math math.private | 
					
						
							|  |  |  | math.functions math.functions.private sequences parser | 
					
						
							|  |  |  | namespaces make assocs quotations arrays generic generic.math | 
					
						
							|  |  |  | hashtables effects compiler.units classes.algebra fry | 
					
						
							|  |  |  | combinators words ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | IN: math.partial-dispatch | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PREDICATE: math-partial < word | 
					
						
							|  |  |  |     "derived-from" word-prop >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | GENERIC: integer-op-input-classes ( word -- classes )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: math-partial integer-op-input-classes | 
					
						
							|  |  |  |     "derived-from" word-prop rest ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-03 02:19:06 -05:00
										 |  |  | ERROR: bad-integer-op word ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | M: word integer-op-input-classes | 
					
						
							| 
									
										
										
										
											2008-11-03 02:19:06 -05:00
										 |  |  |     dup "input-classes" word-prop | 
					
						
							|  |  |  |     [ ] [ bad-integer-op ] ?if ;
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : generic-variant ( op -- generic-op/f )
 | 
					
						
							|  |  |  |     dup "derived-from" word-prop [ first ] [ ] ?if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : no-overflow-variant ( op -- fast-op )
 | 
					
						
							|  |  |  |     H{ | 
					
						
							|  |  |  |         { fixnum+ fixnum+fast } | 
					
						
							|  |  |  |         { fixnum- fixnum-fast } | 
					
						
							|  |  |  |         { fixnum* fixnum*fast } | 
					
						
							|  |  |  |         { fixnum-shift fixnum-shift-fast } | 
					
						
							| 
									
										
										
										
											2008-11-21 03:11:36 -05:00
										 |  |  |         { fixnum/i fixnum/i-fast } | 
					
						
							|  |  |  |         { fixnum/mod fixnum/mod-fast } | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  |     } at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : modular-variant ( op -- fast-op )
 | 
					
						
							|  |  |  |     generic-variant dup H{ | 
					
						
							|  |  |  |         { + fixnum+fast } | 
					
						
							|  |  |  |         { - fixnum-fast } | 
					
						
							|  |  |  |         { * fixnum*fast } | 
					
						
							|  |  |  |         { shift fixnum-shift-fast } | 
					
						
							|  |  |  |         { bitand fixnum-bitand } | 
					
						
							|  |  |  |         { bitor fixnum-bitor } | 
					
						
							|  |  |  |         { bitxor fixnum-bitxor } | 
					
						
							|  |  |  |         { bitnot fixnum-bitnot } | 
					
						
							|  |  |  |     } at swap or ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:44:44 -04:00
										 |  |  | : bignum-fixnum-op-quot ( big-word -- quot )
 | 
					
						
							|  |  |  |     '[ fixnum>bignum _ execute ] ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : fixnum-bignum-op-quot ( big-word -- quot )
 | 
					
						
							|  |  |  |     '[ [ fixnum>bignum ] dip _ execute ] ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | : integer-fixnum-op-quot ( fix-word big-word -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ over fixnum? ] % | 
					
						
							| 
									
										
										
										
											2009-03-16 01:44:44 -04:00
										 |  |  |         [ '[ _ execute ] , ] [ bignum-fixnum-op-quot , ] bi* \ if , | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     ] [ ] make ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | : fixnum-integer-op-quot ( fix-word big-word -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ dup fixnum? ] % | 
					
						
							| 
									
										
										
										
											2009-03-16 01:44:44 -04:00
										 |  |  |         [ '[ _ execute ] , ] [ fixnum-bignum-op-quot , ] bi* \ if , | 
					
						
							|  |  |  |     ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : integer-bignum-op-quot ( big-word -- quot )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ over fixnum? ] % | 
					
						
							|  |  |  |         [ fixnum-bignum-op-quot , ] [ '[ _ execute ] , ] bi \ if , | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     ] [ ] make ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | : integer-integer-op-quot ( fix-word big-word -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-03-16 01:44:44 -04:00
										 |  |  |         [ 2dup both-fixnums? ] % | 
					
						
							|  |  |  |         [ '[ _ execute ] , ] | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |         [ | 
					
						
							| 
									
										
										
										
											2009-03-16 01:44:44 -04:00
										 |  |  |             [ | 
					
						
							|  |  |  |                 [ dup fixnum? ] % | 
					
						
							|  |  |  |                 [ bignum-fixnum-op-quot , ] | 
					
						
							|  |  |  |                 [ integer-bignum-op-quot , ] bi \ if , | 
					
						
							|  |  |  |             ] [ ] make , | 
					
						
							|  |  |  |         ] bi* \ if , | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     ] [ ] make ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  | : integer-op-word ( triple -- word )
 | 
					
						
							|  |  |  |     [ name>> ] map "-" join "math.partial-dispatch" create ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  | : integer-op-quot ( fix-word big-word triple -- quot )
 | 
					
						
							|  |  |  |     [ second ] [ third ] bi 2array { | 
					
						
							|  |  |  |         { { fixnum integer } [ fixnum-integer-op-quot ] } | 
					
						
							|  |  |  |         { { integer fixnum } [ integer-fixnum-op-quot ] } | 
					
						
							|  |  |  |         { { integer integer } [ integer-integer-op-quot ] } | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  | : define-integer-op-word ( fix-word big-word triple -- )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-03-11 14:57:13 -04:00
										 |  |  |         [ 2nip integer-op-word dup make-foldable ] [ integer-op-quot ] 3bi
 | 
					
						
							| 
									
										
										
										
											2011-10-18 16:18:42 -04:00
										 |  |  |         ( x y -- z ) define-declared | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |         2nip
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  |         [ integer-op-word ] keep
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |         "derived-from" set-word-prop | 
					
						
							|  |  |  |     ] 3bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  | : define-integer-op-words ( triples fix-word big-word -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     '[ [ _ _ ] dip define-integer-op-word ] each ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : integer-op-triples ( word -- triples )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { fixnum integer } | 
					
						
							|  |  |  |         { integer fixnum } | 
					
						
							|  |  |  |         { integer integer } | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     } swap '[ _ prefix ] map ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-integer-ops ( word fix-word big-word -- )
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-02-02 14:43:54 -05:00
										 |  |  |         rot
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  |         [ fixnum fixnum 3array "derived-from" set-word-prop ] | 
					
						
							|  |  |  |         [ bignum bignum 3array "derived-from" set-word-prop ] | 
					
						
							| 
									
										
										
										
											2009-02-02 14:43:54 -05:00
										 |  |  |         bi-curry bi*
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         [ integer-op-triples ] 2dip
 | 
					
						
							|  |  |  |         [ define-integer-op-words ] | 
					
						
							|  |  |  |         [ 2drop [ dup integer-op-word ] { } map>assoc % ] | 
					
						
							|  |  |  |         3bi
 | 
					
						
							|  |  |  |     ] 3bi ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-math-ops ( op -- )
 | 
					
						
							|  |  |  |     { fixnum bignum float } | 
					
						
							| 
									
										
										
										
											2011-10-03 18:49:49 -04:00
										 |  |  |     [ [ dup 3array ] [ swap ?lookup-method ] 2bi ] with { } map>assoc
 | 
					
						
							| 
									
										
										
										
											2012-08-24 01:36:10 -04:00
										 |  |  |     sift-values
 | 
					
						
							| 
									
										
										
										
											2008-11-29 14:44:38 -05:00
										 |  |  |     [ def>> ] assoc-map
 | 
					
						
							|  |  |  |     [ nip length 1 = ] assoc-filter
 | 
					
						
							|  |  |  |     [ first ] assoc-map % ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: fast-math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : math-op ( word left right -- word' ? )
 | 
					
						
							|  |  |  |     3array math-ops get at* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : math-method* ( word left right -- quot )
 | 
					
						
							|  |  |  |     3dup math-op | 
					
						
							| 
									
										
										
										
											2008-11-17 17:59:15 -05:00
										 |  |  |     [ [ 3drop ] dip 1quotation ] [ drop math-method ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : math-both-known? ( word left right -- ? )
 | 
					
						
							|  |  |  |     3dup math-op | 
					
						
							| 
									
										
										
										
											2012-10-23 15:21:30 -04:00
										 |  |  |     [ 4drop t ] | 
					
						
							| 
									
										
										
										
											2009-09-21 18:42:20 -04:00
										 |  |  |     [ drop math-class-max swap method-for-class >boolean ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (derived-ops) ( word assoc -- words )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  |     swap '[ swap first _ eq? nip ] assoc-filter ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : derived-ops ( word -- words )
 | 
					
						
							| 
									
										
										
										
											2008-09-12 09:18:44 -04:00
										 |  |  |     [ 1array ] [ math-ops get (derived-ops) values ] bi append ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fast-derived-ops ( word -- words )
 | 
					
						
							| 
									
										
										
										
											2008-09-12 09:18:44 -04:00
										 |  |  |     fast-math-ops get (derived-ops) values ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : all-derived-ops ( word -- words )
 | 
					
						
							|  |  |  |     [ derived-ops ] [ fast-derived-ops ] bi append ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 09:18:44 -04:00
										 |  |  | : integer-derived-ops ( word -- words )
 | 
					
						
							|  |  |  |     [ math-ops get (derived-ops) ] [ fast-math-ops get (derived-ops) ] bi
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-11-30 05:44:52 -05:00
										 |  |  |         [ | 
					
						
							| 
									
										
										
										
											2008-09-12 09:18:44 -04:00
										 |  |  |             drop
 | 
					
						
							|  |  |  |             [ second integer class<= ] | 
					
						
							|  |  |  |             [ third integer class<= ] | 
					
						
							|  |  |  |             bi and
 | 
					
						
							|  |  |  |         ] assoc-filter values
 | 
					
						
							|  |  |  |     ] bi@ append ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | : each-derived-op ( word quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:59:15 -05:00
										 |  |  |     [ derived-ops ] dip each ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : each-fast-derived-op ( word quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:59:15 -05:00
										 |  |  |     [ fast-derived-ops ] dip each ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | : each-integer-derived-op ( word quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:59:15 -05:00
										 |  |  |     [ integer-derived-ops ] dip each ; inline
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | [ | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         \ +       define-math-ops | 
					
						
							|  |  |  |         \ -       define-math-ops | 
					
						
							|  |  |  |         \ *       define-math-ops | 
					
						
							|  |  |  |         \ mod     define-math-ops | 
					
						
							|  |  |  |         \ /i      define-math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         \ bitand  define-math-ops | 
					
						
							|  |  |  |         \ bitor   define-math-ops | 
					
						
							|  |  |  |         \ bitxor  define-math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         \ <       define-math-ops | 
					
						
							|  |  |  |         \ <=      define-math-ops | 
					
						
							|  |  |  |         \ >       define-math-ops | 
					
						
							|  |  |  |         \ >=      define-math-ops | 
					
						
							| 
									
										
										
										
											2009-09-12 23:20:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         \ u<      define-math-ops | 
					
						
							|  |  |  |         \ u<=     define-math-ops | 
					
						
							|  |  |  |         \ u>      define-math-ops | 
					
						
							|  |  |  |         \ u>=     define-math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |         \ number= define-math-ops | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 05:44:52 -05:00
										 |  |  |         { { shift bignum bignum } bignum-shift } , | 
					
						
							|  |  |  |         { { shift fixnum fixnum } fixnum-shift } , | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |         \ + \ fixnum+ \ bignum+ define-integer-ops | 
					
						
							|  |  |  |         \ - \ fixnum- \ bignum- define-integer-ops | 
					
						
							|  |  |  |         \ * \ fixnum* \ bignum* define-integer-ops | 
					
						
							|  |  |  |         \ shift \ fixnum-shift \ bignum-shift define-integer-ops | 
					
						
							|  |  |  |         \ mod \ fixnum-mod \ bignum-mod define-integer-ops | 
					
						
							|  |  |  |         \ /i \ fixnum/i \ bignum/i define-integer-ops | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-05 12:17:52 -04:00
										 |  |  |         \ fast-gcd \ simple-gcd \ bignum-gcd define-integer-ops | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  |         \ bitand \ fixnum-bitand \ bignum-bitand define-integer-ops | 
					
						
							|  |  |  |         \ bitor \ fixnum-bitor \ bignum-bitor define-integer-ops | 
					
						
							|  |  |  |         \ bitxor \ fixnum-bitxor \ bignum-bitxor define-integer-ops | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         \ < \ fixnum< \ bignum< define-integer-ops | 
					
						
							|  |  |  |         \ <= \ fixnum<= \ bignum<= define-integer-ops | 
					
						
							|  |  |  |         \ > \ fixnum> \ bignum> define-integer-ops | 
					
						
							|  |  |  |         \ >= \ fixnum>= \ bignum>= define-integer-ops | 
					
						
							|  |  |  |         \ number= \ eq? \ bignum= define-integer-ops | 
					
						
							|  |  |  |     ] { } make >hashtable math-ops set-global
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  |     H{ | 
					
						
							|  |  |  |         { { + fixnum fixnum } fixnum+fast } | 
					
						
							|  |  |  |         { { - fixnum fixnum } fixnum-fast } | 
					
						
							|  |  |  |         { { * fixnum fixnum } fixnum*fast } | 
					
						
							|  |  |  |         { { shift fixnum fixnum } fixnum-shift-fast } | 
					
						
							|  |  |  |     } fast-math-ops set-global
 | 
					
						
							| 
									
										
										
										
											2008-07-22 05:45:03 -04:00
										 |  |  | ] with-compilation-unit |