2005-02-24 22:32:51 -05:00
|
|
|
IN: algebra
|
2005-02-27 21:53:11 -05:00
|
|
|
USING: kernel lists math namespaces test stdio words parser
|
|
|
|
|
generic errors prettyprint vectors kernel-internals ;
|
2005-02-24 22:32:51 -05:00
|
|
|
|
|
|
|
|
SYMBOL: variable?
|
|
|
|
|
#! For word props: will this be a var in an infix expression?
|
|
|
|
|
PREDICATE: word var
|
|
|
|
|
#! Class of variables
|
|
|
|
|
variable? word-property ;
|
|
|
|
|
SYMBOL: constant?
|
|
|
|
|
#! Word prop for things like pi and e
|
|
|
|
|
PREDICATE: word con
|
|
|
|
|
constant? word-property ;
|
|
|
|
|
|
|
|
|
|
PREDICATE: cons single
|
|
|
|
|
#! Single-element list
|
|
|
|
|
cdr not ;
|
|
|
|
|
UNION: num/vc number var con ;
|
|
|
|
|
PREDICATE: cons list-word
|
|
|
|
|
#! List where first element is a word but not a variable
|
|
|
|
|
unswons tuck word? and [ var? not ] [ drop f ] ifte ;
|
|
|
|
|
PREDICATE: cons list-nvl
|
|
|
|
|
#! List where first element is a number, variable, or list
|
|
|
|
|
unswons dup num/vc? swap cons? or and ;
|
|
|
|
|
UNION: num/con number con ;
|
|
|
|
|
|
|
|
|
|
GENERIC: infix ( list -- list )
|
|
|
|
|
#! Parse an infix expression. This is right associative
|
|
|
|
|
#! and everything has equal precendence. The output is
|
|
|
|
|
#! an s-expression. Operators can be unary or binary.
|
|
|
|
|
M: num/vc infix ;
|
|
|
|
|
M: single infix car infix ;
|
|
|
|
|
M: list-word infix
|
|
|
|
|
uncons infix 2list ;
|
|
|
|
|
M: list-nvl infix
|
|
|
|
|
unswons infix swap uncons infix swapd 3list ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
: ([
|
|
|
|
|
#! Begin a literal infix expression
|
|
|
|
|
[ ] ; parsing
|
|
|
|
|
: ])
|
|
|
|
|
#! End a literal infix expression.
|
|
|
|
|
reverse infix swons ; parsing
|
|
|
|
|
|
|
|
|
|
: VARIABLE:
|
|
|
|
|
#! Make a variable, which acts like a symbol
|
|
|
|
|
CREATE dup define-symbol t variable? set-word-property ; parsing
|
|
|
|
|
VARIABLE: x
|
|
|
|
|
VARIABLE: y
|
|
|
|
|
VARIABLE: z
|
|
|
|
|
VARIABLE: a
|
|
|
|
|
VARIABLE: b
|
|
|
|
|
VARIABLE: c
|
|
|
|
|
|
|
|
|
|
SYMBOL: arith-1
|
|
|
|
|
#! Word prop for unary mathematical function
|
|
|
|
|
SYMBOL: arith-2
|
|
|
|
|
#! Word prop for binary mathematical function
|
|
|
|
|
|
|
|
|
|
PREDICATE: cons list2
|
|
|
|
|
#! List of 2 elements
|
|
|
|
|
length 2 = ;
|
|
|
|
|
PREDICATE: cons list3
|
|
|
|
|
#! List of 3 elements
|
|
|
|
|
length 3 = ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GENERIC: (eval-infix) ( varstuff infix -- quote )
|
|
|
|
|
|
|
|
|
|
M: num/con (eval-infix)
|
|
|
|
|
nip unit \ drop swons ;
|
|
|
|
|
|
|
|
|
|
: (find) ( counter item list -- index )
|
|
|
|
|
dup [
|
|
|
|
|
2dup car = [ 2drop ] [ >r >r 1 + r> r> cdr (find) ] ifte
|
|
|
|
|
] [
|
|
|
|
|
"Undefined variable in infix expression" throw
|
|
|
|
|
] ifte ;
|
|
|
|
|
: find ( list item -- index )
|
|
|
|
|
0 -rot swap (find) ;
|
|
|
|
|
M: var (eval-infix)
|
2005-02-27 21:53:11 -05:00
|
|
|
find [ swap array-nth ] cons ;
|
2005-02-24 22:32:51 -05:00
|
|
|
|
|
|
|
|
: swap-in-infix ( var fix1 fix2 -- [ fix1solved swap fix2solved ] )
|
|
|
|
|
>r dupd (eval-infix) swap r> (eval-infix) \ swap swons append ;
|
|
|
|
|
M: list3 (eval-infix)
|
|
|
|
|
unswons arith-2 word-property unit -rot 2unlist
|
|
|
|
|
swap-in-infix \ dup swons swap append ;
|
|
|
|
|
|
|
|
|
|
M: list2 (eval-infix)
|
|
|
|
|
2unlist swapd (eval-infix) swap arith-1 word-property unit append ;
|
|
|
|
|
|
2005-02-27 21:53:11 -05:00
|
|
|
: build-prefix ( num-of-vars -- quote )
|
|
|
|
|
#! What needs to be placed in front of the eval-infix quote
|
|
|
|
|
[ dup , \ <array> , dup [
|
|
|
|
|
2dup - 1 - [ swap set-array-nth ] cons , \ keep ,
|
|
|
|
|
] repeat drop ] make-list ;
|
2005-02-24 22:32:51 -05:00
|
|
|
|
2005-02-27 21:53:11 -05:00
|
|
|
: eval-infix ( vars infix -- quote )
|
2005-02-24 22:32:51 -05:00
|
|
|
#! Given a list of variables and an infix expression in s-expression
|
|
|
|
|
#! form, build a quotation which takes as many arguments from the
|
|
|
|
|
#! datastack as there are elements in the varnames list, builds
|
|
|
|
|
#! it into a vector, and calculates the values of the expression with
|
|
|
|
|
#! the values filled in.
|
2005-02-27 21:53:11 -05:00
|
|
|
over length build-prefix -rot (eval-infix) append ;
|
2005-02-24 22:32:51 -05:00
|
|
|
|
2005-02-24 22:53:15 -05:00
|
|
|
DEFER: fold-consts
|
2005-02-24 22:32:51 -05:00
|
|
|
: (| f ; parsing
|
|
|
|
|
: | reverse f ; parsing
|
|
|
|
|
: |) reverse infix fold-consts eval-infix swons \ call swons ; parsing
|
|
|
|
|
|
|
|
|
|
: (fac) dup 0 = [ drop ] [ dup 1 - >r * r> (fac) ] ifte ;
|
|
|
|
|
: fac
|
|
|
|
|
#! Factorial
|
|
|
|
|
1 swap (fac) ;
|
|
|
|
|
|
|
|
|
|
: infix-relation
|
|
|
|
|
#! Wraps operators like = and > so that if they're given
|
|
|
|
|
#! f as either argument, they return f, and they return f if
|
|
|
|
|
#! the operation yields f, but if it yields t, it returns the
|
|
|
|
|
#! left argument. This way, these types of operations can be
|
|
|
|
|
#! composed.
|
|
|
|
|
>r 2dup and not [
|
|
|
|
|
r> 3drop f
|
|
|
|
|
] [
|
|
|
|
|
dupd r> call [
|
|
|
|
|
drop f
|
|
|
|
|
] unless
|
|
|
|
|
] ifte ;
|
|
|
|
|
! Wrapped operations
|
|
|
|
|
: new= [ = ] infix-relation ;
|
|
|
|
|
: new> [ > ] infix-relation ;
|
|
|
|
|
: new< [ < ] infix-relation ;
|
|
|
|
|
: new>= [ >= ] infix-relation ;
|
|
|
|
|
: new<= [ <= ] infix-relation ;
|
|
|
|
|
|
|
|
|
|
: +- ( a b -- a+b a-b )
|
|
|
|
|
[ + ] 2keep - ;
|
|
|
|
|
|
|
|
|
|
! Install arithmetic operators into words
|
2005-02-25 00:06:30 -05:00
|
|
|
[ + - / * ^ and or xor mod +- min gcd max bitand polar> align shift /mod /i /f rect> bitor proj
|
2005-02-27 21:53:11 -05:00
|
|
|
bitxor dot rem ] [
|
|
|
|
|
dup arith-2 set-word-property
|
2005-02-25 00:06:30 -05:00
|
|
|
] each
|
2005-02-24 22:32:51 -05:00
|
|
|
[ [[ = new= ]] [[ > new> ]] [[ < new< ]] [[ >= new>= ]] [[ <= new<= ]] ] [
|
|
|
|
|
uncons arith-2 set-word-property
|
|
|
|
|
] each
|
2005-02-27 21:53:11 -05:00
|
|
|
[ sqrt abs fac sq asin denominator rational? rad>deg exp recip sgn >rect acoth arg fixnum
|
2005-02-25 00:06:30 -05:00
|
|
|
bitnot sinh acosec acosh acosech complex? ratio? number? >polar number= cis deg>rad >fixnum
|
|
|
|
|
cot cos sec cosec tan imaginary coth asech atanh absq >float numerator acot acos atan asec
|
|
|
|
|
cosh log bignum? conjugate asinh sin float? real? >bignum tanh sech ] [
|
|
|
|
|
dup arith-1 set-word-property
|
|
|
|
|
] each
|
2005-02-24 22:32:51 -05:00
|
|
|
[ [[ - neg ]] ] [ uncons arith-1 set-word-property ] each
|
|
|
|
|
[ pi i e -i inf -inf pi/2 ] [ t constant? set-word-property ] each
|