fix trees for <=>

a bit of refactoring to use new accessors, i hope wrunt doesn't mind
db4
Doug Coleman 2008-04-27 23:23:59 -05:00
parent 09c21f077b
commit e0639d0547
1 changed files with 32 additions and 40 deletions

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel generic math sequences arrays io namespaces USING: kernel generic math sequences arrays io namespaces
prettyprint.private kernel.private assocs random combinators prettyprint.private kernel.private assocs random combinators
parser prettyprint.backend math.order ; parser prettyprint.backend math.order accessors ;
IN: trees IN: trees
MIXIN: tree-mixin MIXIN: tree-mixin
@ -25,19 +25,14 @@ TUPLE: node key value left right ;
SYMBOL: current-side SYMBOL: current-side
: left -1 ; inline : go-left? ( -- ? ) current-side get +lt+ eq? ;
: right 1 ; inline
: go-left? ( -- ? ) current-side get left = ; : inc-count ( tree -- ) [ 1+ ] change-count drop ;
: inc-count ( tree -- ) : dec-count ( tree -- ) [ 1- ] change-count drop ;
dup tree-count 1+ swap set-tree-count ;
: dec-count ( tree -- )
dup tree-count 1- swap set-tree-count ;
: node-link@ ( node ? -- node ) : node-link@ ( node ? -- node )
go-left? xor [ node-left ] [ node-right ] if ; go-left? xor [ left>> ] [ right>> ] if ;
: set-node-link@ ( left parent ? -- ) : set-node-link@ ( left parent ? -- )
go-left? xor [ set-node-left ] [ set-node-right ] if ; go-left? xor [ set-node-left ] [ set-node-right ] if ;
@ -47,24 +42,21 @@ SYMBOL: current-side
: set-node+link ( child node -- ) t set-node-link@ ; : set-node+link ( child node -- ) t set-node-link@ ;
: with-side ( side quot -- ) [ swap current-side set call ] with-scope ; inline : with-side ( side quot -- ) [ swap current-side set call ] with-scope ; inline
: with-other-side ( quot -- ) current-side get neg swap with-side ; inline : with-other-side ( quot -- )
: go-left ( quot -- ) left swap with-side ; inline current-side get invert-comparison swap with-side ; inline
: go-right ( quot -- ) right swap with-side ; inline : go-left ( quot -- ) +lt+ swap with-side ; inline
: go-right ( quot -- ) +gt+ swap with-side ; inline
: change-root ( tree quot -- ) : change-root ( tree quot -- )
swap [ tree-root swap call ] keep set-tree-root ; inline swap [ root>> swap call ] keep set-tree-root ; inline
: leaf? ( node -- ? ) : leaf? ( node -- ? )
dup node-left swap node-right or not ; [ left>> ] [ right>> ] bi or not ;
: key-side ( k1 k2 -- side ) : random-side ( -- side ) +lt+ +gt+ 2array random ;
#! side is -1 if k1 < k2, 0 if they are equal, or 1 if k1 > k2
<=> sgn ;
: random-side ( -- side ) left right 2array random ;
: choose-branch ( key node -- key node-left/right ) : choose-branch ( key node -- key node-left/right )
2dup node-key key-side [ node-link ] with-side ; 2dup node-key <=> [ node-link ] with-side ;
: node-at* ( key node -- value ? ) : node-at* ( key node -- value ? )
[ [
@ -76,11 +68,11 @@ SYMBOL: current-side
] [ drop f f ] if* ; ] [ drop f f ] if* ;
M: tree at* ( key tree -- value ? ) M: tree at* ( key tree -- value ? )
tree-root node-at* ; root>> node-at* ;
: node-set ( value key node -- node ) : node-set ( value key node -- node )
2dup node-key key-side dup zero? [ 2dup key>> <=> dup +eq+ eq? [
drop nip [ set-node-value ] keep drop nip swap >>value
] [ ] [
[ [
[ node-link [ node-set ] [ swap <node> ] if* ] keep [ node-link [ node-set ] [ swap <node> ] if* ] keep
@ -93,12 +85,12 @@ M: tree set-at ( value key tree -- )
: valid-node? ( node -- ? ) : valid-node? ( node -- ? )
[ [
dup dup node-left [ node-key swap node-key before? ] when* >r dup dup left>> [ node-key swap node-key before? ] when* >r
dup dup node-right [ node-key swap node-key after? ] when* r> and swap dup dup right>> [ node-key swap node-key after? ] when* r> and swap
dup node-left valid-node? swap node-right valid-node? and and dup left>> valid-node? swap right>> valid-node? and and
] [ t ] if* ; ] [ t ] if* ;
: valid-tree? ( tree -- ? ) tree-root valid-node? ; : valid-tree? ( tree -- ? ) root>> valid-node? ;
: tree-call ( node call -- ) : tree-call ( node call -- )
>r [ node-key ] keep node-value r> call ; inline >r [ node-key ] keep node-value r> call ; inline
@ -107,20 +99,20 @@ M: tree set-at ( value key tree -- )
{ {
{ [ over not ] [ 2drop f f f ] } { [ over not ] [ 2drop f f f ] }
{ [ [ { [ [
>r node-left r> find-node >r left>> r> find-node
] 2keep rot ] ] 2keep rot ]
[ 2drop t ] } [ 2drop t ] }
{ [ >r 2nip r> [ tree-call ] 2keep rot ] { [ >r 2nip r> [ tree-call ] 2keep rot ]
[ drop [ node-key ] keep node-value t ] } [ drop [ node-key ] keep node-value t ] }
[ >r node-right r> find-node ] [ >r right>> r> find-node ]
} cond ; inline } cond ; inline
M: tree-mixin assoc-find ( tree quot -- key value ? ) M: tree-mixin assoc-find ( tree quot -- key value ? )
>r tree-root r> find-node ; >r root>> r> find-node ;
M: tree-mixin clear-assoc M: tree-mixin clear-assoc
0 over set-tree-count 0 >>count
f swap set-tree-root ; f >>root drop ;
: copy-node-contents ( new old -- ) : copy-node-contents ( new old -- )
dup node-key pick set-node-key node-value swap set-node-value ; dup node-key pick set-node-key node-value swap set-node-value ;
@ -158,22 +150,22 @@ DEFER: delete-node
: delete-node ( node -- node ) : delete-node ( node -- node )
#! delete this node, returning its replacement #! delete this node, returning its replacement
dup node-left [ dup left>> [
dup node-right [ dup right>> [
delete-node-with-two-children delete-node-with-two-children
] [ ] [
node-left ! left but no right left>> ! left but no right
] if ] if
] [ ] [
dup node-right [ dup right>> [
node-right ! right but not left right>> ! right but not left
] [ ] [
drop f ! no children drop f ! no children
] if ] if
] if ; ] if ;
: delete-bst-node ( key node -- node ) : delete-bst-node ( key node -- node )
2dup node-key key-side dup zero? [ 2dup node-key <=> dup +eq+ eq? [
drop nip delete-node drop nip delete-node
] [ ] [
[ tuck node-link delete-bst-node over set-node-link ] with-side [ tuck node-link delete-bst-node over set-node-link ] with-side
@ -197,7 +189,7 @@ M: tree-mixin assoc-like drop dup tree? [ >tree ] unless ;
M: tree pprint-delims drop \ TREE{ \ } ; M: tree pprint-delims drop \ TREE{ \ } ;
M: tree-mixin assoc-size tree-count ; M: tree-mixin assoc-size count>> ;
M: tree-mixin clone dup assoc-clone-like ; M: tree-mixin clone dup assoc-clone-like ;
M: tree-mixin >pprint-sequence >alist ; M: tree-mixin >pprint-sequence >alist ;
M: tree-mixin pprint-narrow? drop t ; M: tree-mixin pprint-narrow? drop t ;