Merge branch 'bags' of git://github.com/littledan/Factor

Conflicts:

	basis/compiler/cfg/ssa/construction/tdmsc/tdmsc.factor
	basis/furnace/auth/auth.factor
	basis/stack-checker/backend/backend.factor
db4
Daniel Ehrenberg 2010-03-16 13:28:00 -04:00
commit 512fe14e4e
113 changed files with 656 additions and 288 deletions

View File

@ -0,0 +1,18 @@
USING: help.markup help.syntax sequences math ;
IN: bit-sets
ARTICLE: "bit-sets" "Bit sets"
"The " { $vocab-link "bit-sets" } " vocabulary implements bit-array-backed sets. Bitsets are efficient for implementing relatively dense sets whose members are in a contiguous range of integers starting from 0. One bit is required for each integer in this range in the underlying representation."
"Bit sets are of the class"
{ $subsection bit-set }
"They can be instantiated with the word"
{ $subsection <bit-set> } ;
ABOUT: "bit-sets"
HELP: bit-set
{ $class-description "The class of bit-array-based sets. These implement the " { $link "sets" } "." } ;
HELP: <bit-set>
{ $values { "capacity" integer } { "bit-set" bit-set } }
{ $description "Creates a new bit set with the given capacity. This set is initially empty and can contain as members integers between 0 and " { $snippet "capacity" } "-1." } ;

View File

@ -1,17 +1,63 @@
USING: bit-sets tools.test bit-arrays ; USING: bit-sets tools.test sets kernel bit-arrays ;
IN: bit-sets.tests IN: bit-sets.tests
[ ?{ t f t f t f } ] [ [ T{ bit-set f ?{ t f t f t f } } ] [
?{ t f f f t f } T{ bit-set f ?{ t f f f t f } }
?{ f f t f t f } bit-set-union T{ bit-set f ?{ f f t f t f } } union
] unit-test ] unit-test
[ ?{ f f f f t f } ] [ [ T{ bit-set f ?{ f f f f t f } } ] [
?{ t f f f t f } T{ bit-set f ?{ t f f f t f } }
?{ f f t f t f } bit-set-intersect T{ bit-set f ?{ f f t f t f } } intersect
] unit-test ] unit-test
[ ?{ t f t f f f } ] [ [ T{ bit-set f ?{ t f t f f f } } ] [
?{ t t t f f f } T{ bit-set f ?{ t t t f f f } }
?{ f t f f t t } bit-set-diff T{ bit-set f ?{ f t f f t t } } diff
] unit-test ] unit-test
[ f ] [
T{ bit-set f ?{ t t t f f f } }
T{ bit-set f ?{ f t f f t t } } subset?
] unit-test
[ t ] [
T{ bit-set f ?{ t t t f f f } }
T{ bit-set f ?{ f t f f f f } } subset?
] unit-test
[ t ] [
{ 0 1 2 }
T{ bit-set f ?{ f t f f f f } } subset?
] unit-test
[ f ] [
T{ bit-set f ?{ f t f f f f } }
T{ bit-set f ?{ t t t f f f } } subset?
] unit-test
[ f ] [
{ 1 }
T{ bit-set f ?{ t t t f f f } } subset?
] unit-test
[ V{ 0 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } members ] unit-test
[ t V{ 1 2 3 } ] [
{ 1 2 } 5 <bit-set> set-like
[ bit-set? ] keep
3 over adjoin
members
] unit-test
[ V{ 0 1 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } clone [ 1 swap adjoin ] keep members ] unit-test
[ T{ bit-set f ?{ t f t f f t } } clone [ 9 swap adjoin ] keep members ] must-fail
[ T{ bit-set f ?{ t f t f f t } } clone [ "foo" swap adjoin ] keep members ] must-fail
[ V{ 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } clone [ 0 swap delete ] keep members ] unit-test
[ V{ 0 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } clone [ 1 swap delete ] keep members ] unit-test
[ V{ 0 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } clone [ 9 swap delete ] keep members ] unit-test
[ V{ 0 2 5 } ] [ T{ bit-set f ?{ t f t f f t } } clone [ "foo" swap delete ] keep members ] unit-test
[ T{ bit-set f ?{ f } } T{ bit-set f ?{ t } } ]
[ 1 <bit-set> dup clone 0 over adjoin ] unit-test

View File

@ -1,8 +1,33 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors sequences byte-arrays bit-arrays math hints ; USING: kernel accessors sequences byte-arrays bit-arrays math hints sets ;
IN: bit-sets IN: bit-sets
TUPLE: bit-set { table bit-array read-only } ;
: <bit-set> ( capacity -- bit-set )
<bit-array> bit-set boa ;
INSTANCE: bit-set set
M: bit-set in?
over integer? [ table>> ?nth ] [ 2drop f ] if ; inline
M: bit-set adjoin
! This is allowed to crash when the elt couldn't go in the set
[ t ] 2dip table>> set-nth ;
M: bit-set delete
! This isn't allowed to crash if the elt wasn't in the set
over integer? [
table>> 2dup bounds-check? [
[ f ] 2dip set-nth
] [ 2drop ] if
] [ 2drop ] if ;
! If you do binary set operations with a bitset, it's expected
! that the other thing can also be represented as a bitset
! of the same length.
<PRIVATE <PRIVATE
: bit-set-map ( seq1 seq2 quot -- seq ) : bit-set-map ( seq1 seq2 quot -- seq )
@ -14,18 +39,36 @@ IN: bit-sets
] dip 2map ] dip 2map
] 3bi bit-array boa ; inline ] 3bi bit-array boa ; inline
: (bit-set-op) ( set1 set2 -- table1 table2 )
[ set-like ] keep [ table>> ] bi@ ; inline
: bit-set-op ( set1 set2 quot: ( a b -- c ) -- bit-set )
[ (bit-set-op) ] dip bit-set-map bit-set boa ; inline
PRIVATE> PRIVATE>
: bit-set-union ( seq1 seq2 -- seq ) [ bitor ] bit-set-map ; M: bit-set union
[ bitor ] bit-set-op ;
HINTS: bit-set-union bit-array bit-array ; M: bit-set intersect
[ bitand ] bit-set-op ;
: bit-set-intersect ( seq1 seq2 -- seq ) [ bitand ] bit-set-map ; M: bit-set diff
[ bitnot bitand ] bit-set-op ;
HINTS: bit-set-intersect bit-array bit-array ; M: bit-set subset?
[ intersect ] keep = ;
: bit-set-diff ( seq1 seq2 -- seq ) [ bitnot bitand ] bit-set-map ; M: bit-set members
[ table>> length iota ] keep [ in? ] curry filter ;
HINTS: bit-set-diff bit-array bit-array ; M: bit-set set-like
! This crashes if there are keys that can't be put in the bit set
over bit-set? [ 2dup [ table>> ] bi@ length = ] [ f ] if
[ drop ] [
[ members ] dip table>> length <bit-set>
[ [ adjoin ] curry each ] keep
] if ;
: bit-set-subset? ( seq1 seq2 -- ? ) dupd bit-set-intersect = ; M: bit-set clone
table>> clone bit-set boa ;

View File

@ -12,6 +12,7 @@ compiler.cfg.registers
compiler.cfg.comparisons compiler.cfg.comparisons
compiler.cfg.instructions compiler.cfg.instructions
compiler.cfg.representations.preferred ; compiler.cfg.representations.preferred ;
FROM: namespaces => set ;
IN: compiler.cfg.alias-analysis IN: compiler.cfg.alias-analysis
! We try to eliminate redundant slot operations using some simple heuristics. ! We try to eliminate redundant slot operations using some simple heuristics.
@ -297,14 +298,14 @@ SYMBOL: live-stores
histories get histories get
values [ values [
values [ [ store? ] filter [ insn#>> ] map ] map concat values [ [ store? ] filter [ insn#>> ] map ] map concat
] map concat unique ] map concat fast-set
live-stores set ; live-stores set ;
GENERIC: eliminate-dead-stores* ( insn -- insn' ) GENERIC: eliminate-dead-stores* ( insn -- insn' )
: (eliminate-dead-stores) ( insn -- insn' ) : (eliminate-dead-stores) ( insn -- insn' )
dup insn-slot# [ dup insn-slot# [
insn# get live-stores get key? [ insn# get live-stores get in? [
drop f drop f
] unless ] unless
] when ; ] when ;

View File

@ -1,8 +1,9 @@
! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg. ! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs sets kernel namespaces sequences USING: accessors assocs kernel namespaces sequences
compiler.cfg.instructions compiler.cfg.def-use compiler.cfg.instructions compiler.cfg.def-use
compiler.cfg.rpo compiler.cfg.predecessors ; compiler.cfg.rpo compiler.cfg.predecessors hash-sets sets ;
FROM: namespaces => set ;
IN: compiler.cfg.dce IN: compiler.cfg.dce
! Maps vregs to sequences of vregs ! Maps vregs to sequences of vregs
@ -12,18 +13,18 @@ SYMBOL: liveness-graph
SYMBOL: live-vregs SYMBOL: live-vregs
: live-vreg? ( vreg -- ? ) : live-vreg? ( vreg -- ? )
live-vregs get key? ; live-vregs get in? ;
! vregs which are the result of an allocation ! vregs which are the result of an allocation
SYMBOL: allocations SYMBOL: allocations
: allocation? ( vreg -- ? ) : allocation? ( vreg -- ? )
allocations get key? ; allocations get in? ;
: init-dead-code ( -- ) : init-dead-code ( -- )
H{ } clone liveness-graph set H{ } clone liveness-graph set
H{ } clone live-vregs set HS{ } clone live-vregs set
H{ } clone allocations set ; HS{ } clone allocations set ;
GENERIC: build-liveness-graph ( insn -- ) GENERIC: build-liveness-graph ( insn -- )
@ -46,7 +47,7 @@ M: ##write-barrier-imm build-liveness-graph
dup src>> setter-liveness-graph ; dup src>> setter-liveness-graph ;
M: ##allot build-liveness-graph M: ##allot build-liveness-graph
[ dst>> allocations get conjoin ] [ call-next-method ] bi ; [ dst>> allocations get adjoin ] [ call-next-method ] bi ;
M: insn build-liveness-graph M: insn build-liveness-graph
dup defs-vreg dup [ add-edges ] [ 2drop ] if ; dup defs-vreg dup [ add-edges ] [ 2drop ] if ;
@ -55,8 +56,8 @@ GENERIC: compute-live-vregs ( insn -- )
: (record-live) ( vregs -- ) : (record-live) ( vregs -- )
[ [
dup live-vregs get key? [ drop ] [ dup live-vreg? [ drop ] [
[ live-vregs get conjoin ] [ live-vregs get adjoin ]
[ liveness-graph get at (record-live) ] [ liveness-graph get at (record-live) ]
bi bi
] if ] if

View File

@ -5,6 +5,8 @@ compiler.units fry generalizations generic kernel locals
namespaces quotations sequences sets slots words namespaces quotations sequences sets slots words
compiler.cfg.instructions compiler.cfg.instructions.syntax compiler.cfg.instructions compiler.cfg.instructions.syntax
compiler.cfg.rpo ; compiler.cfg.rpo ;
FROM: namespaces => set ;
FROM: sets => members ;
IN: compiler.cfg.def-use IN: compiler.cfg.def-use
GENERIC: defs-vreg ( insn -- vreg/f ) GENERIC: defs-vreg ( insn -- vreg/f )
@ -94,9 +96,9 @@ SYMBOLS: defs insns uses ;
cfg [| block | cfg [| block |
block instructions>> [ block instructions>> [
dup ##phi? dup ##phi?
[ inputs>> [ use conjoin-at ] assoc-each ] [ inputs>> [ use adjoin-at ] assoc-each ]
[ uses-vregs [ block swap use conjoin-at ] each ] [ uses-vregs [ block swap use adjoin-at ] each ]
if if
] each ] each
] each-basic-block ] each-basic-block
use [ keys ] assoc-map uses set ; use [ members ] assoc-map uses set ;

View File

@ -3,6 +3,7 @@
USING: accessors assocs combinators sets math fry kernel math.order USING: accessors assocs combinators sets math fry kernel math.order
dlists deques vectors namespaces sequences sorting locals dlists deques vectors namespaces sequences sorting locals
compiler.cfg.rpo compiler.cfg.predecessors ; compiler.cfg.rpo compiler.cfg.predecessors ;
FROM: namespaces => set ;
IN: compiler.cfg.dominance IN: compiler.cfg.dominance
! Reference: ! Reference:
@ -103,4 +104,4 @@ PRIVATE>
[ accum push ] [ accum push ]
[ dom-children work-list push-all-front ] bi [ dom-children work-list push-all-front ] bi
] slurp-deque ] slurp-deque
accum ; accum ;

View File

@ -13,6 +13,7 @@ compiler.cfg.linearization.order
compiler.cfg.linear-scan.allocation compiler.cfg.linear-scan.allocation
compiler.cfg.linear-scan.allocation.state compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.live-intervals ; compiler.cfg.linear-scan.live-intervals ;
FROM: namespaces => set ;
IN: compiler.cfg.linear-scan.assignment IN: compiler.cfg.linear-scan.assignment
! This contains both active and inactive intervals; any interval ! This contains both active and inactive intervals; any interval

View File

@ -3,6 +3,7 @@
USING: accessors kernel sequences sets arrays math strings fry USING: accessors kernel sequences sets arrays math strings fry
namespaces prettyprint compiler.cfg.linear-scan.live-intervals namespaces prettyprint compiler.cfg.linear-scan.live-intervals
compiler.cfg.linear-scan.allocation compiler.cfg assocs ; compiler.cfg.linear-scan.allocation compiler.cfg assocs ;
FROM: namespaces => set ;
IN: compiler.cfg.linear-scan.debugger IN: compiler.cfg.linear-scan.debugger
: check-linear-scan ( live-intervals machine-registers -- ) : check-linear-scan ( live-intervals machine-registers -- )

View File

@ -1,4 +1,3 @@
IN: compiler.cfg.linear-scan.tests
USING: tools.test random sorting sequences sets hashtables assocs USING: tools.test random sorting sequences sets hashtables assocs
kernel fry arrays splitting namespaces math accessors vectors locals kernel fry arrays splitting namespaces math accessors vectors locals
math.order grouping strings strings.private classes layouts math.order grouping strings strings.private classes layouts
@ -21,6 +20,8 @@ compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.allocation.splitting compiler.cfg.linear-scan.allocation.splitting
compiler.cfg.linear-scan.allocation.spilling compiler.cfg.linear-scan.allocation.spilling
compiler.cfg.linear-scan.debugger ; compiler.cfg.linear-scan.debugger ;
FROM: namespaces => set ;
IN: compiler.cfg.linear-scan.tests
check-allocation? on check-allocation? on
check-numbering? on check-numbering? on

View File

@ -2,8 +2,10 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs deques dlists kernel make sorting USING: accessors assocs deques dlists kernel make sorting
namespaces sequences combinators combinators.short-circuit namespaces sequences combinators combinators.short-circuit
fry math sets compiler.cfg.rpo compiler.cfg.utilities fry math compiler.cfg.rpo compiler.cfg.utilities
compiler.cfg.loop-detection compiler.cfg.predecessors ; compiler.cfg.loop-detection compiler.cfg.predecessors
sets hash-sets ;
FROM: namespaces => set ;
IN: compiler.cfg.linearization.order IN: compiler.cfg.linearization.order
! This is RPO except loops are rotated. Based on SBCL's src/compiler/control.lisp ! This is RPO except loops are rotated. Based on SBCL's src/compiler/control.lisp
@ -12,16 +14,16 @@ IN: compiler.cfg.linearization.order
SYMBOLS: work-list loop-heads visited ; SYMBOLS: work-list loop-heads visited ;
: visited? ( bb -- ? ) visited get key? ; : visited? ( bb -- ? ) visited get in? ;
: add-to-work-list ( bb -- ) : add-to-work-list ( bb -- )
dup visited get key? [ drop ] [ dup visited? [ drop ] [
work-list get push-back work-list get push-back
] if ; ] if ;
: init-linearization-order ( cfg -- ) : init-linearization-order ( cfg -- )
<dlist> work-list set <dlist> work-list set
H{ } clone visited set HS{ } clone visited set
entry>> add-to-work-list ; entry>> add-to-work-list ;
: (find-alternate-loop-head) ( bb -- bb' ) : (find-alternate-loop-head) ( bb -- bb' )
@ -58,7 +60,7 @@ SYMBOLS: work-list loop-heads visited ;
: process-block ( bb -- ) : process-block ( bb -- )
dup visited? [ drop ] [ dup visited? [ drop ] [
[ , ] [ , ]
[ visited get conjoin ] [ visited get adjoin ]
[ sorted-successors [ process-successor ] each ] [ sorted-successors [ process-successor ] each ]
tri tri
] if ; ] if ;
@ -76,4 +78,4 @@ PRIVATE>
dup linear-order>> [ ] [ dup linear-order>> [ ] [
dup (linearization-order) dup (linearization-order)
>>linear-order linear-order>> >>linear-order linear-order>>
] ?if ; ] ?if ;

View File

@ -4,6 +4,7 @@ USING: kernel namespaces deques accessors sets sequences assocs fry
hashtables dlists compiler.cfg.def-use compiler.cfg.instructions hashtables dlists compiler.cfg.def-use compiler.cfg.instructions
compiler.cfg.rpo compiler.cfg.liveness compiler.cfg.utilities compiler.cfg.rpo compiler.cfg.liveness compiler.cfg.utilities
compiler.cfg.predecessors ; compiler.cfg.predecessors ;
FROM: namespaces => set ;
IN: compiler.cfg.liveness.ssa IN: compiler.cfg.liveness.ssa
! TODO: merge with compiler.cfg.liveness ! TODO: merge with compiler.cfg.liveness
@ -59,4 +60,4 @@ SYMBOL: work-list
: live-in? ( vreg bb -- ? ) live-in key? ; : live-in? ( vreg bb -- ? ) live-in key? ;
: live-out? ( vreg bb -- ? ) live-out key? ; : live-out? ( vreg bb -- ? ) live-out key? ;

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators deques dlists fry kernel USING: accessors assocs combinators deques dlists fry kernel
namespaces sequences sets compiler.cfg compiler.cfg.predecessors ; namespaces sequences sets compiler.cfg compiler.cfg.predecessors ;
FROM: namespaces => set ;
IN: compiler.cfg.loop-detection IN: compiler.cfg.loop-detection
TUPLE: natural-loop header index ends blocks ; TUPLE: natural-loop header index ends blocks ;

View File

@ -5,6 +5,7 @@ words sets combinators generalizations cpu.architecture compiler.units
compiler.cfg.utilities compiler.cfg compiler.cfg.rpo compiler.cfg.utilities compiler.cfg compiler.cfg.rpo
compiler.cfg.instructions compiler.cfg.def-use ; compiler.cfg.instructions compiler.cfg.def-use ;
FROM: compiler.cfg.instructions.syntax => insn-def-slot insn-use-slots insn-temp-slots scalar-rep ; FROM: compiler.cfg.instructions.syntax => insn-def-slot insn-use-slots insn-temp-slots scalar-rep ;
FROM: namespaces => set ;
IN: compiler.cfg.representations.preferred IN: compiler.cfg.representations.preferred
GENERIC: defs-vreg-rep ( insn -- rep/f ) GENERIC: defs-vreg-rep ( insn -- rep/f )

View File

@ -15,6 +15,7 @@ compiler.cfg.utilities
compiler.cfg.loop-detection compiler.cfg.loop-detection
compiler.cfg.renaming.functor compiler.cfg.renaming.functor
compiler.cfg.representations.preferred ; compiler.cfg.representations.preferred ;
FROM: namespaces => set ;
IN: compiler.cfg.representations IN: compiler.cfg.representations
! Virtual register representation selection. ! Virtual register representation selection.

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors namespaces make math sequences sets USING: kernel accessors namespaces make math sequences sets
assocs fry compiler.cfg compiler.cfg.instructions ; assocs fry compiler.cfg compiler.cfg.instructions ;
FROM: namespaces => set ;
IN: compiler.cfg.rpo IN: compiler.cfg.rpo
SYMBOL: visited SYMBOL: visited

View File

@ -12,6 +12,7 @@ compiler.cfg.instructions
compiler.cfg.renaming compiler.cfg.renaming
compiler.cfg.renaming.functor compiler.cfg.renaming.functor
compiler.cfg.ssa.construction.tdmsc ; compiler.cfg.ssa.construction.tdmsc ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.construction IN: compiler.cfg.ssa.construction
! The phi placement algorithm is implemented in ! The phi placement algorithm is implemented in
@ -135,4 +136,4 @@ PRIVATE>
[ compute-defs compute-phi-nodes insert-phi-nodes ] [ compute-defs compute-phi-nodes insert-phi-nodes ]
[ rename ] [ rename ]
[ ] [ ]
} cleave ; } cleave ;

View File

@ -2,6 +2,7 @@ USING: accessors arrays compiler.cfg compiler.cfg.debugger
compiler.cfg.dominance compiler.cfg.predecessors compiler.cfg.dominance compiler.cfg.predecessors
compiler.cfg.ssa.construction.tdmsc kernel namespaces sequences compiler.cfg.ssa.construction.tdmsc kernel namespaces sequences
tools.test vectors sets ; tools.test vectors sets ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.construction.tdmsc.tests IN: compiler.cfg.ssa.construction.tdmsc.tests
: test-tdmsc ( -- ) : test-tdmsc ( -- )
@ -70,4 +71,4 @@ V{ } 7 test-bb
[ ] [ test-tdmsc ] unit-test [ ] [ test-tdmsc ] unit-test
[ V{ 2 } ] [ { 2 3 4 5 } [ get ] map merge-set [ number>> ] map ] unit-test [ V{ 2 } ] [ { 2 3 4 5 } [ get ] map merge-set [ number>> ] map ] unit-test
[ V{ } ] [ { 0 1 6 7 } [ get ] map merge-set ] unit-test [ V{ } ] [ { 0 1 6 7 } [ get ] map merge-set ] unit-test

View File

@ -3,6 +3,7 @@
USING: accessors arrays assocs bit-arrays bit-sets fry USING: accessors arrays assocs bit-arrays bit-sets fry
hashtables hints kernel locals math namespaces sequences sets hashtables hints kernel locals math namespaces sequences sets
compiler.cfg compiler.cfg.dominance compiler.cfg.rpo ; compiler.cfg compiler.cfg.dominance compiler.cfg.rpo ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.construction.tdmsc IN: compiler.cfg.ssa.construction.tdmsc
! TDMSC-I algorithm from "A Practical and Fast Iterative Algorithm for ! TDMSC-I algorithm from "A Practical and Fast Iterative Algorithm for
@ -15,7 +16,7 @@ IN: compiler.cfg.ssa.construction.tdmsc
SYMBOLS: visited merge-sets levels again? ; SYMBOLS: visited merge-sets levels again? ;
: init-merge-sets ( cfg -- ) : init-merge-sets ( cfg -- )
post-order dup length '[ _ <bit-array> ] H{ } map>assoc merge-sets set ; post-order dup length '[ _ <bit-set> ] H{ } map>assoc merge-sets set ;
: compute-levels ( cfg -- ) : compute-levels ( cfg -- )
0 over entry>> associate [ 0 over entry>> associate [
@ -29,15 +30,12 @@ SYMBOLS: visited merge-sets levels again? ;
: level ( bb -- n ) levels get at ; inline : level ( bb -- n ) levels get at ; inline
: set-bit ( bit-array n -- )
[ t ] 2dip swap set-nth ;
: update-merge-set ( tmp to -- ) : update-merge-set ( tmp to -- )
[ merge-sets get ] dip [ merge-sets get ] dip
'[ '[
_ _
[ merge-sets get at bit-set-union ] [ merge-sets get at union ]
[ dupd number>> set-bit ] [ number>> over adjoin ]
bi bi
] change-at ; ] change-at ;
@ -51,10 +49,10 @@ SYMBOLS: visited merge-sets levels again? ;
[ [ predecessors>> ] keep ] dip [ [ predecessors>> ] keep ] dip
'[ _ 2dup j-edge? _ [ 2drop ] if ] each ; inline '[ _ 2dup j-edge? _ [ 2drop ] if ] each ; inline
: visited? ( pair -- ? ) visited get key? ; : visited? ( pair -- ? ) visited get in? ;
: consistent? ( snode lnode -- ? ) : consistent? ( snode lnode -- ? )
[ merge-sets get at ] bi@ swap bit-set-subset? ; [ merge-sets get at ] bi@ subset? ;
: (process-edge) ( from to -- ) : (process-edge) ( from to -- )
f walk [ f walk [
@ -65,7 +63,7 @@ SYMBOLS: visited merge-sets levels again? ;
: process-edge ( from to -- ) : process-edge ( from to -- )
2dup 2array dup visited? [ 3drop ] [ 2dup 2array dup visited? [ 3drop ] [
visited get conjoin visited get adjoin
(process-edge) (process-edge)
] if ; ] if ;
@ -73,7 +71,7 @@ SYMBOLS: visited merge-sets levels again? ;
[ process-edge ] each-incoming-j-edge ; [ process-edge ] each-incoming-j-edge ;
: compute-merge-set-step ( bfo -- ) : compute-merge-set-step ( bfo -- )
visited get clear-assoc HS{ } clone visited set
[ process-block ] each ; [ process-block ] each ;
: compute-merge-set-loop ( cfg -- ) : compute-merge-set-loop ( cfg -- )
@ -82,29 +80,22 @@ SYMBOLS: visited merge-sets levels again? ;
loop ; loop ;
: (merge-set) ( bbs -- flags rpo ) : (merge-set) ( bbs -- flags rpo )
merge-sets get '[ _ at ] [ bit-set-union ] map-reduce merge-sets get '[ _ at ] [ union ] map-reduce
cfg get reverse-post-order ; inline cfg get reverse-post-order ; inline
: filter-by ( flags seq -- seq' )
[ drop ] selector [ 2each ] dip ;
HINTS: filter-by { bit-array object } ;
PRIVATE> PRIVATE>
: compute-merge-sets ( cfg -- ) : compute-merge-sets ( cfg -- )
needs-dominance needs-dominance
H{ } clone visited set HS{ } clone visited set
[ compute-levels ] [ compute-levels ]
[ init-merge-sets ] [ init-merge-sets ]
[ compute-merge-set-loop ] [ compute-merge-set-loop ]
tri ; tri ;
: merge-set-each ( ... bbs quot: ( ... bb -- ... ) -- ... )
[ (merge-set) ] dip '[
swap _ [ drop ] if
] 2each ; inline
: merge-set ( bbs -- bbs' ) : merge-set ( bbs -- bbs' )
(merge-set) filter-by ; (merge-set) [ members ] dip nths ;
: merge-set-each ( bbs quot: ( bb -- ) -- )
[ merge-set ] dip each ; inline

View File

@ -15,6 +15,7 @@ compiler.cfg.ssa.interference
compiler.cfg.ssa.interference.live-ranges compiler.cfg.ssa.interference.live-ranges
compiler.cfg.utilities compiler.cfg.utilities
compiler.utilities ; compiler.utilities ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.destruction IN: compiler.cfg.ssa.destruction
! Maps vregs to leaders. ! Maps vregs to leaders.

View File

@ -6,6 +6,7 @@ compiler.cfg.rpo
compiler.cfg.dominance compiler.cfg.dominance
compiler.cfg.def-use compiler.cfg.def-use
compiler.cfg.instructions ; compiler.cfg.instructions ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.liveness IN: compiler.cfg.ssa.liveness
! Liveness checking on SSA IR, as described in ! Liveness checking on SSA IR, as described in

View File

@ -8,6 +8,7 @@ compiler.cfg.instructions
compiler.cfg.registers compiler.cfg.registers
compiler.cfg.stacks.height compiler.cfg.stacks.height
compiler.cfg.parallel-copy ; compiler.cfg.parallel-copy ;
FROM: namespaces => set ;
IN: compiler.cfg.stacks.local IN: compiler.cfg.stacks.local
! Local stack analysis. We build three sets for every basic block ! Local stack analysis. We build three sets for every basic block
@ -106,4 +107,4 @@ M: rs-loc translate-local-loc n>> current-height get r>> - <rs-loc> ;
: peek-set ( bb -- assoc ) peek-sets get at ; : peek-set ( bb -- assoc ) peek-sets get at ;
: replace-set ( bb -- assoc ) replace-sets get at ; : replace-set ( bb -- assoc ) replace-sets get at ;
: kill-set ( bb -- assoc ) kill-sets get at ; : kill-set ( bb -- assoc ) kill-sets get at ;

View File

@ -3,6 +3,7 @@
USING: accessors assocs combinators.short-circuit USING: accessors assocs combinators.short-circuit
compiler.cfg.instructions compiler.cfg.rpo kernel namespaces compiler.cfg.instructions compiler.cfg.rpo kernel namespaces
sequences sets ; sequences sets ;
FROM: namespaces => set ;
IN: compiler.cfg.write-barrier IN: compiler.cfg.write-barrier
SYMBOL: fresh-allocations SYMBOL: fresh-allocations

View File

@ -16,6 +16,7 @@ compiler.cfg.registers
compiler.cfg.builder compiler.cfg.builder
compiler.codegen.fixup compiler.codegen.fixup
compiler.utilities ; compiler.utilities ;
FROM: namespaces => set ;
IN: compiler.codegen IN: compiler.codegen
SYMBOL: insn-counts SYMBOL: insn-counts

View File

@ -7,6 +7,7 @@ compiler.tree
compiler.tree.def-use compiler.tree.def-use
compiler.tree.recursive compiler.tree.recursive
compiler.tree.combinators ; compiler.tree.combinators ;
FROM: namespaces => set ;
IN: compiler.tree.checker IN: compiler.tree.checker
! Check some invariants; this can help catch compiler bugs. ! Check some invariants; this can help catch compiler bugs.

View File

@ -4,6 +4,7 @@ USING: sequences namespaces kernel accessors assocs sets fry
arrays combinators columns stack-checker.backend arrays combinators columns stack-checker.backend
stack-checker.branches compiler.tree compiler.tree.combinators stack-checker.branches compiler.tree compiler.tree.combinators
compiler.tree.dead-code.liveness compiler.tree.dead-code.simple ; compiler.tree.dead-code.liveness compiler.tree.dead-code.simple ;
FROM: namespaces => set ;
IN: compiler.tree.dead-code.branches IN: compiler.tree.dead-code.branches
M: #if mark-live-values* look-at-inputs ; M: #if mark-live-values* look-at-inputs ;

View File

@ -4,6 +4,7 @@ USING: fry accessors namespaces assocs deques search-deques
dlists kernel sequences compiler.utilities words sets dlists kernel sequences compiler.utilities words sets
stack-checker.branches compiler.tree compiler.tree.def-use stack-checker.branches compiler.tree compiler.tree.def-use
compiler.tree.combinators ; compiler.tree.combinators ;
FROM: namespaces => set ;
IN: compiler.tree.dead-code.liveness IN: compiler.tree.dead-code.liveness
SYMBOL: work-list SYMBOL: work-list

View File

@ -6,6 +6,8 @@ stack-checker.state
stack-checker.branches stack-checker.branches
compiler.tree compiler.tree
compiler.tree.combinators ; compiler.tree.combinators ;
FROM: namespaces => set ;
FROM: sets => members ;
IN: compiler.tree.def-use IN: compiler.tree.def-use
SYMBOL: def-use SYMBOL: def-use
@ -42,7 +44,7 @@ GENERIC: node-uses-values ( node -- values )
M: #introduce node-uses-values drop f ; M: #introduce node-uses-values drop f ;
M: #push node-uses-values drop f ; M: #push node-uses-values drop f ;
M: #phi node-uses-values phi-in-d>> concat remove-bottom prune ; M: #phi node-uses-values phi-in-d>> concat remove-bottom members ;
M: #declare node-uses-values drop f ; M: #declare node-uses-values drop f ;
M: #terminate node-uses-values [ in-d>> ] [ in-r>> ] bi append ; M: #terminate node-uses-values [ in-d>> ] [ in-r>> ] bi append ;
M: #shuffle node-uses-values [ in-d>> ] [ in-r>> ] bi append ; M: #shuffle node-uses-values [ in-d>> ] [ in-r>> ] bi append ;

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: sequences kernel fry vectors accessors namespaces assocs sets USING: sequences kernel fry vectors accessors namespaces assocs sets
stack-checker.branches compiler.tree compiler.tree.def-use ; stack-checker.branches compiler.tree compiler.tree.def-use ;
FROM: namespaces => set ;
IN: compiler.tree.def-use.simplified IN: compiler.tree.def-use.simplified
! Simplified def-use follows chains of copies. ! Simplified def-use follows chains of copies.

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs namespaces sequences kernel math USING: accessors assocs namespaces sequences kernel math
combinators sets disjoint-sets fry stack-checker.values ; combinators sets disjoint-sets fry stack-checker.values ;
FROM: namespaces => set ;
IN: compiler.tree.escape-analysis.allocations IN: compiler.tree.escape-analysis.allocations
! A map from values to classes. Only for #introduce outputs ! A map from values to classes. Only for #introduce outputs

View File

@ -9,6 +9,7 @@ compiler.tree.propagation.info
compiler.tree.def-use compiler.tree.def-use
compiler.tree.def-use.simplified compiler.tree.def-use.simplified
compiler.tree.late-optimizations ; compiler.tree.late-optimizations ;
FROM: namespaces => set ;
IN: compiler.tree.modular-arithmetic IN: compiler.tree.modular-arithmetic
! This is a late-stage optimization. ! This is a late-stage optimization.

View File

@ -9,6 +9,7 @@ vectors hashtables combinators effects generalizations assocs
sets combinators.short-circuit sequences.private locals growable sets combinators.short-circuit sequences.private locals growable
stack-checker namespaces compiler.tree.propagation.info ; stack-checker namespaces compiler.tree.propagation.info ;
FROM: math => float ; FROM: math => float ;
FROM: sets => set ;
IN: compiler.tree.propagation.transforms IN: compiler.tree.propagation.transforms
\ equal? [ \ equal? [
@ -134,6 +135,7 @@ IN: compiler.tree.propagation.transforms
in-d>> first value-info literal>> { in-d>> first value-info literal>> {
{ V{ } [ [ drop { } 0 vector boa ] ] } { V{ } [ [ drop { } 0 vector boa ] ] }
{ H{ } [ [ drop 0 <hashtable> ] ] } { H{ } [ [ drop 0 <hashtable> ] ] }
{ HS{ } [ [ drop f fast-set ] ] }
[ drop f ] [ drop f ]
} case } case
] "custom-inlining" set-word-prop ] "custom-inlining" set-word-prop
@ -207,7 +209,7 @@ ERROR: bad-partial-eval quot word ;
[ drop f ] swap [ drop f ] swap
[ literalize [ t ] ] { } map>assoc linear-case-quot [ literalize [ t ] ] { } map>assoc linear-case-quot
] [ ] [
unique [ key? ] curry tester
] if ; ] if ;
\ member? [ \ member? [
@ -272,14 +274,14 @@ CONSTANT: lookup-table-at-max 256
\ at* [ at-quot ] 1 define-partial-eval \ at* [ at-quot ] 1 define-partial-eval
: diff-quot ( seq -- quot: ( seq' -- seq'' ) ) : diff-quot ( seq -- quot: ( seq' -- seq'' ) )
tester '[ [ @ not ] filter ] ; tester '[ [ [ @ not ] filter ] keep set-like ] ;
\ diff [ diff-quot ] 1 define-partial-eval M\ set diff [ diff-quot ] 1 define-partial-eval
: intersect-quot ( seq -- quot: ( seq' -- seq'' ) ) : intersect-quot ( seq -- quot: ( seq' -- seq'' ) )
tester '[ _ filter ] ; tester '[ [ _ filter ] keep set-like ] ;
\ intersect [ intersect-quot ] 1 define-partial-eval M\ set intersect [ intersect-quot ] 1 define-partial-eval
: fixnum-bits ( -- n ) : fixnum-bits ( -- n )
cell-bits tag-bits get - ; cell-bits tag-bits get - ;

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel assocs arrays namespaces accessors sequences deques fry USING: kernel assocs arrays namespaces accessors sequences deques fry
search-deques dlists combinators.short-circuit make sets compiler.tree ; search-deques dlists combinators.short-circuit make sets compiler.tree ;
FROM: namespaces => set ;
IN: compiler.tree.recursive IN: compiler.tree.recursive
TUPLE: call-site tail? node label ; TUPLE: call-site tail? node label ;

View File

@ -4,6 +4,7 @@ USING: sequences kernel splitting lists fry accessors assocs math.order
math combinators namespaces urls.encoding xml.syntax xmode.code2html math combinators namespaces urls.encoding xml.syntax xmode.code2html
xml.data arrays strings vectors xml.writer io.streams.string locals xml.data arrays strings vectors xml.writer io.streams.string locals
unicode.categories ; unicode.categories ;
FROM: namespaces => set ;
IN: farkup IN: farkup
SYMBOL: relative-link-prefix SYMBOL: relative-link-prefix

View File

@ -15,6 +15,7 @@ furnace.boilerplate
furnace.auth.providers furnace.auth.providers
furnace.auth.providers.db ; furnace.auth.providers.db ;
FROM: assocs => change-at ; FROM: assocs => change-at ;
FROM: namespaces => set ;
IN: furnace.auth IN: furnace.auth
SYMBOL: logged-in-user SYMBOL: logged-in-user

View File

@ -62,4 +62,4 @@ ARTICLE: "crossref-test-1" "Crossref test 1"
ARTICLE: "crossref-test-2" "Crossref test 2" ARTICLE: "crossref-test-2" "Crossref test 2"
{ $markup-example { $subsection "crossref-test-1" } } ; { $markup-example { $subsection "crossref-test-1" } } ;
[ V{ } ] [ "crossref-test-2" >link article-children ] unit-test [ { } ] [ "crossref-test-2" >link article-children ] unit-test

View File

@ -166,6 +166,7 @@ ARTICLE: "collections" "Collections"
} }
{ $heading "Other collections" } { $heading "Other collections" }
{ $subsections { $subsections
"sets"
"lists" "lists"
"disjoint-sets" "disjoint-sets"
"interval-maps" "interval-maps"

View File

@ -6,6 +6,7 @@ help help.markup help.topics io.streams.string kernel macros
namespaces sequences sequences.deep sets sorting splitting namespaces sequences sequences.deep sets sorting splitting
strings unicode.categories values vocabs vocabs.loader words strings unicode.categories values vocabs vocabs.loader words
words.symbol summary debugger io ; words.symbol summary debugger io ;
FROM: sets => members ;
IN: help.lint.checks IN: help.lint.checks
ERROR: simple-lint-error message ; ERROR: simple-lint-error message ;
@ -48,7 +49,7 @@ SYMBOL: vocab-articles
: effect-values ( word -- seq ) : effect-values ( word -- seq )
stack-effect stack-effect
[ in>> ] [ out>> ] bi append [ in>> ] [ out>> ] bi append
[ dup pair? [ first ] when effect>string ] map prune ; [ dup pair? [ first ] when effect>string ] map members ;
: effect-effects ( word -- seq ) : effect-effects ( word -- seq )
stack-effect in>> [ stack-effect in>> [
@ -103,7 +104,7 @@ SYMBOL: vocab-articles
: check-see-also ( element -- ) : check-see-also ( element -- )
\ $see-also swap elements [ \ $see-also swap elements [
rest dup prune [ length ] bi@ assert= rest all-unique? t assert=
] each ; ] each ;
: vocab-exists? ( name -- ? ) : vocab-exists? ( name -- ? )

View File

@ -8,6 +8,7 @@ prettyprint.stylesheet quotations see sequences sets slots
sorting splitting strings vectors vocabs vocabs.loader words sorting splitting strings vectors vocabs vocabs.loader words
words.symbol ; words.symbol ;
FROM: prettyprint.sections => with-pprint ; FROM: prettyprint.sections => with-pprint ;
FROM: namespaces => set ;
IN: help.markup IN: help.markup
PREDICATE: simple-element < array PREDICATE: simple-element < array
@ -441,7 +442,7 @@ M: array elements*
: elements ( elt-type element -- seq ) [ elements* ] { } make ; : elements ( elt-type element -- seq ) [ elements* ] { } make ;
: collect-elements ( element seq -- elements ) : collect-elements ( element seq -- elements )
swap '[ _ elements [ rest ] map concat ] map concat prune ; swap '[ _ elements [ rest ] map concat ] gather ;
: <$link> ( topic -- element ) : <$link> ( topic -- element )
1array \ $link prefix ; 1array \ $link prefix ;

View File

@ -5,6 +5,7 @@ namespaces prettyprint prettyprint.custom prettyprint.sections
sequences strings io.styles vectors words quotations mirrors sequences strings io.styles vectors words quotations mirrors
splitting math.parser classes vocabs sets sorting summary splitting math.parser classes vocabs sets sorting summary
debugger continuations fry combinators ; debugger continuations fry combinators ;
FROM: namespaces => set ;
IN: inspector IN: inspector
SYMBOL: +number-rows+ SYMBOL: +number-rows+

View File

@ -81,7 +81,7 @@ M: linux-monitor dispose* ( monitor -- )
IN_MOVED_FROM +rename-file-old+ ?flag IN_MOVED_FROM +rename-file-old+ ?flag
IN_MOVED_TO +rename-file-new+ ?flag IN_MOVED_TO +rename-file-new+ ?flag
drop drop
] { } make prune ; ] { } make members ;
: parse-event-name ( event -- name ) : parse-event-name ( event -- name )
dup len>> zero? dup len>> zero?

View File

@ -18,7 +18,7 @@ GENERIC: rewrite-closures* ( obj -- )
GENERIC: defs-vars* ( seq form -- seq' ) GENERIC: defs-vars* ( seq form -- seq' )
: defs-vars ( form -- vars ) { } [ defs-vars* ] reduce prune ; : defs-vars ( form -- vars ) { } [ defs-vars* ] reduce members ;
M: def defs-vars* local>> unquote suffix ; M: def defs-vars* local>> unquote suffix ;
@ -28,7 +28,7 @@ M: object defs-vars* drop ;
GENERIC: uses-vars* ( seq form -- seq' ) GENERIC: uses-vars* ( seq form -- seq' )
: uses-vars ( form -- vars ) { } [ uses-vars* ] reduce prune ; : uses-vars ( form -- vars ) { } [ uses-vars* ] reduce members ;
M: local-writer uses-vars* "local-reader" word-prop suffix ; M: local-writer uses-vars* "local-reader" word-prop suffix ;

View File

@ -23,5 +23,5 @@ IN: math.ranges.tests
[ { 0 1/3 2/3 1 } ] [ 1 0 -1/3 <range> >array reverse ] unit-test [ { 0 1/3 2/3 1 } ] [ 1 0 -1/3 <range> >array reverse ] unit-test
[ 100 ] [ [ 100 ] [
1 100 [a,b] [ 2^ [1,b] ] map prune length 1 100 [a,b] [ 2^ [1,b] ] map members length
] unit-test ] unit-test

View File

@ -5,6 +5,7 @@ io vectors arrays math.parser math.order combinators classes
sets unicode.categories compiler.units parser effects.parser sets unicode.categories compiler.units parser effects.parser
words quotations memoize accessors locals splitting words quotations memoize accessors locals splitting
combinators.short-circuit generalizations ; combinators.short-circuit generalizations ;
FROM: namespaces => set ;
IN: peg IN: peg
TUPLE: parse-result remaining ast ; TUPLE: parse-result remaining ast ;

View File

@ -6,7 +6,8 @@ combinators continuations effects generic hashtables io
io.pathnames io.styles kernel make math math.order math.parser io.pathnames io.styles kernel make math math.order math.parser
namespaces prettyprint.config prettyprint.custom namespaces prettyprint.config prettyprint.custom
prettyprint.sections prettyprint.stylesheet quotations sbufs prettyprint.sections prettyprint.stylesheet quotations sbufs
sequences strings vectors words words.symbol ; sequences strings vectors words words.symbol hash-sets ;
FROM: sets => members ;
IN: prettyprint.backend IN: prettyprint.backend
M: effect pprint* effect>string "(" ")" surround text ; M: effect pprint* effect>string "(" ")" surround text ;
@ -187,6 +188,7 @@ M: hashtable pprint-delims drop \ H{ \ } ;
M: tuple pprint-delims drop \ T{ \ } ; M: tuple pprint-delims drop \ T{ \ } ;
M: wrapper pprint-delims drop \ W{ \ } ; M: wrapper pprint-delims drop \ W{ \ } ;
M: callstack pprint-delims drop \ CS{ \ } ; M: callstack pprint-delims drop \ CS{ \ } ;
M: hash-set pprint-delims drop \ HS{ \ } ;
M: object >pprint-sequence ; M: object >pprint-sequence ;
M: vector >pprint-sequence ; M: vector >pprint-sequence ;
@ -195,6 +197,7 @@ M: callable >pprint-sequence ;
M: hashtable >pprint-sequence >alist ; M: hashtable >pprint-sequence >alist ;
M: wrapper >pprint-sequence wrapped>> 1array ; M: wrapper >pprint-sequence wrapped>> 1array ;
M: callstack >pprint-sequence callstack>array ; M: callstack >pprint-sequence callstack>array ;
M: hash-set >pprint-sequence members ;
: class-slot-sequence ( class slots -- sequence ) : class-slot-sequence ( class slots -- sequence )
[ 1array ] [ [ f 2array ] dip append ] if-empty ; [ 1array ] [ [ f 2array ] dip append ] if-empty ;
@ -226,6 +229,7 @@ M: byte-vector pprint* pprint-object ;
M: hashtable pprint* pprint-object ; M: hashtable pprint* pprint-object ;
M: curry pprint* pprint-object ; M: curry pprint* pprint-object ;
M: compose pprint* pprint-object ; M: compose pprint* pprint-object ;
M: hash-set pprint* pprint-object ;
M: wrapper pprint* M: wrapper pprint*
{ {

View File

@ -5,6 +5,7 @@ io.streams.string io.styles kernel make math math.parser namespaces
parser prettyprint.backend prettyprint.config prettyprint.custom parser prettyprint.backend prettyprint.config prettyprint.custom
prettyprint.sections quotations sequences sorting strings vocabs prettyprint.sections quotations sequences sorting strings vocabs
vocabs.prettyprint words sets generic ; vocabs.prettyprint words sets generic ;
FROM: namespaces => set ;
IN: prettyprint IN: prettyprint
: with-use ( obj quot -- ) : with-use ( obj quot -- )

View File

@ -4,6 +4,7 @@ USING: arrays generic hashtables io kernel math assocs
namespaces make sequences strings io.styles vectors words namespaces make sequences strings io.styles vectors words
prettyprint.config splitting classes continuations prettyprint.config splitting classes continuations
accessors sets vocabs.parser combinators vocabs ; accessors sets vocabs.parser combinators vocabs ;
FROM: namespaces => set ;
IN: prettyprint.sections IN: prettyprint.sections
! State ! State

View File

@ -14,7 +14,7 @@ IN: random.tests
[ t ] [ 10000 [ iota 0 [ drop 187 random + ] reduce ] keep / 2 * 187 10 ~ ] unit-test [ t ] [ 10000 [ iota 0 [ drop 187 random + ] reduce ] keep / 2 * 187 10 ~ ] unit-test
[ t ] [ 10000 [ iota 0 [ drop 400 random + ] reduce ] keep / 2 * 400 10 ~ ] unit-test [ t ] [ 10000 [ iota 0 [ drop 400 random + ] reduce ] keep / 2 * 400 10 ~ ] unit-test
[ t ] [ 1000 [ 400 random ] replicate prune length 256 > ] unit-test [ t ] [ 1000 [ 400 random ] replicate members length 256 > ] unit-test
[ f ] [ 0 random ] unit-test [ f ] [ 0 random ] unit-test
@ -28,8 +28,8 @@ IN: random.tests
[ { 1 2 } 3 sample ] [ too-many-samples? ] must-fail-with [ { 1 2 } 3 sample ] [ too-many-samples? ] must-fail-with
[ 3 ] [ { 1 2 3 4 } 3 sample prune length ] unit-test [ 3 ] [ { 1 2 3 4 } 3 sample members length ] unit-test
[ 99 ] [ 100 iota 99 sample prune length ] unit-test [ 99 ] [ 100 iota 99 sample members length ] unit-test
[ ] [ ]
[ [ 100 random-bytes ] with-system-random drop ] unit-test [ [ 100 random-bytes ] with-system-random drop ] unit-test

View File

@ -36,7 +36,7 @@ IN: regexp.classes.tests
! Making classes into nested conditionals ! Making classes into nested conditionals
[ V{ 1 2 3 4 } ] [ T{ and-class f { 1 T{ not-class f 2 } T{ or-class f { 3 4 } } 2 } } class>questions ] unit-test [ { 1 2 3 4 } ] [ T{ and-class f { 1 T{ not-class f 2 } T{ or-class f { 3 4 } } 2 } } class>questions ] unit-test
[ { 3 } ] [ { { 3 t } } table>condition ] unit-test [ { 3 } ] [ { { 3 t } } table>condition ] unit-test
[ { T{ primitive-class } } ] [ { { 1 t } { 2 T{ primitive-class } } } table>questions ] unit-test [ { T{ primitive-class } } ] [ { { 1 t } { 2 T{ primitive-class } } } table>questions ] unit-test
[ { { 1 t } { 2 t } } ] [ { { 1 t } { 2 T{ primitive-class } } } T{ primitive-class } t assoc-answer ] unit-test [ { { 1 t } { 2 t } } ] [ { { 1 t } { 2 T{ primitive-class } } } T{ primitive-class } t assoc-answer ] unit-test

View File

@ -5,6 +5,7 @@ unicode.categories combinators.short-circuit sequences
fry macros arrays assocs sets classes mirrors unicode.script fry macros arrays assocs sets classes mirrors unicode.script
unicode.data ; unicode.data ;
FROM: ascii => ascii? ; FROM: ascii => ascii? ;
FROM: sets => members ;
IN: regexp.classes IN: regexp.classes
SINGLETONS: dot letter-class LETTER-class Letter-class digit-class SINGLETONS: dot letter-class LETTER-class Letter-class digit-class
@ -157,7 +158,7 @@ DEFER: substitute
TUPLE: class-partition integers not-integers simples not-simples and or other ; TUPLE: class-partition integers not-integers simples not-simples and or other ;
: partition-classes ( seq -- class-partition ) : partition-classes ( seq -- class-partition )
prune members
[ integer? ] partition [ integer? ] partition
[ not-integer? ] partition [ not-integer? ] partition
[ simple-class? ] partition [ simple-class? ] partition
@ -194,7 +195,7 @@ TUPLE: class-partition integers not-integers simples not-simples and or other ;
[ t swap remove ] change-other [ t swap remove ] change-other
dup contradiction? dup contradiction?
[ drop f ] [ drop f ]
[ filter-not-integers class-partition>seq prune t and-class seq>instance ] if ; [ filter-not-integers class-partition>seq members t and-class seq>instance ] if ;
: <and-class> ( seq -- class ) : <and-class> ( seq -- class )
dup and-class flatten partition-classes dup and-class flatten partition-classes
@ -225,7 +226,7 @@ TUPLE: class-partition integers not-integers simples not-simples and or other ;
[ f swap remove ] change-other [ f swap remove ] change-other
dup tautology? dup tautology?
[ drop t ] [ drop t ]
[ filter-integers class-partition>seq prune f or-class seq>instance ] if ; [ filter-integers class-partition>seq members f or-class seq>instance ] if ;
: <or-class> ( seq -- class ) : <or-class> ( seq -- class )
dup or-class flatten partition-classes dup or-class flatten partition-classes
@ -329,7 +330,7 @@ M: object class>questions 1array ;
: condition-states ( condition -- states ) : condition-states ( condition -- states )
dup condition? [ dup condition? [
[ yes>> ] [ no>> ] bi [ yes>> ] [ no>> ] bi
[ condition-states ] bi@ append prune [ condition-states ] bi@ union
] [ 1array ] if ; ] [ 1array ] if ;
: condition-at ( condition assoc -- new-condition ) : condition-at ( condition assoc -- new-condition )

View File

@ -1,7 +1,7 @@
! Copyright (C) 2009 Daniel Ehrenberg. ! Copyright (C) 2009 Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: regexp.classes kernel sequences regexp.negation USING: regexp.classes kernel sequences regexp.negation
quotations assocs fry math locals combinators quotations assocs fry math locals combinators sets
accessors words compiler.units kernel.private strings accessors words compiler.units kernel.private strings
sequences.private arrays namespaces unicode.breaks sequences.private arrays namespaces unicode.breaks
regexp.transition-tables combinators.short-circuit ; regexp.transition-tables combinators.short-circuit ;
@ -106,7 +106,7 @@ C: <box> box
: word>quot ( word dfa -- quot ) : word>quot ( word dfa -- quot )
[ transitions>> at ] [ transitions>> at ]
[ final-states>> key? ] 2bi [ final-states>> in? ] 2bi
transitions>quot ; transitions>quot ;
: states>code ( words dfa -- ) : states>code ( words dfa -- )

View File

@ -69,10 +69,10 @@ IN: regexp.dfa
: set-final-states ( nfa dfa -- ) : set-final-states ( nfa dfa -- )
[ [
[ final-states>> keys ] [ final-states>> members ]
[ transitions>> keys ] bi* [ transitions>> keys ] bi*
[ intersects? ] with filter [ intersects? ] with filter
unique fast-set
] keep (>>final-states) ; ] keep (>>final-states) ;
: initialize-dfa ( nfa -- dfa ) : initialize-dfa ( nfa -- dfa )

View File

@ -34,7 +34,7 @@ IN: regexp.minimize.tests
{ 3 H{ } } { 3 H{ } }
} } } }
{ start-state 0 } { start-state 0 }
{ final-states H{ { 3 3 } } } { final-states HS{ 3 } }
} }
] [ ] [
T{ transition-table T{ transition-table
@ -48,7 +48,7 @@ IN: regexp.minimize.tests
{ 6 H{ } } { 6 H{ } }
} } } }
{ start-state 0 } { start-state 0 }
{ final-states H{ { 3 3 } { 6 6 } } } { final-states HS{ 3 6 } }
} combine-states } combine-states
] unit-test ] unit-test

View File

@ -19,7 +19,7 @@ IN: regexp.minimize
{ {
[ drop <= ] [ drop <= ]
[ transitions>> '[ _ at keys ] bi@ set= ] [ transitions>> '[ _ at keys ] bi@ set= ]
[ final-states>> '[ _ key? ] bi@ = ] [ final-states>> '[ _ in? ] bi@ = ]
} 3&& ; } 3&& ;
:: initialize-partitions ( transition-table -- partitions ) :: initialize-partitions ( transition-table -- partitions )

View File

@ -12,7 +12,7 @@ IN: regexp.negation.tests
{ -1 H{ { t -1 } } } { -1 H{ { t -1 } } }
} } } }
{ start-state 0 } { start-state 0 }
{ final-states H{ { 0 0 } { -1 -1 } } } { final-states HS{ 0 -1 } }
} }
] [ ] [
! R/ a/ ! R/ a/
@ -22,6 +22,6 @@ IN: regexp.negation.tests
{ 1 H{ } } { 1 H{ } }
} } } }
{ start-state 0 } { start-state 0 }
{ final-states H{ { 1 1 } } } { final-states HS{ 1 } }
} negate-table } negate-table
] unit-test ] unit-test

View File

@ -3,7 +3,7 @@
USING: regexp.nfa regexp.disambiguate kernel sequences USING: regexp.nfa regexp.disambiguate kernel sequences
assocs regexp.classes hashtables accessors fry vectors assocs regexp.classes hashtables accessors fry vectors
regexp.ast regexp.transition-tables regexp.minimize regexp.ast regexp.transition-tables regexp.minimize
regexp.dfa namespaces ; regexp.dfa namespaces sets ;
IN: regexp.negation IN: regexp.negation
CONSTANT: fail-state -1 CONSTANT: fail-state -1
@ -21,7 +21,7 @@ CONSTANT: fail-state -1
fail-state-recurses ; fail-state-recurses ;
: inverse-final-states ( transition-table -- final-states ) : inverse-final-states ( transition-table -- final-states )
[ transitions>> assoc>set ] [ final-states>> ] bi assoc-diff ; [ transitions>> keys ] [ final-states>> ] bi diff fast-set ;
: negate-table ( transition-table -- transition-table ) : negate-table ( transition-table -- transition-table )
clone clone
@ -36,14 +36,14 @@ CONSTANT: fail-state -1
[ [ [ 1vector ] assoc-map ] assoc-map ] change-transitions ; [ [ [ 1vector ] assoc-map ] assoc-map ] change-transitions ;
: unify-final-state ( transition-table -- transition-table ) : unify-final-state ( transition-table -- transition-table )
dup [ final-states>> keys ] keep dup [ final-states>> members ] keep
'[ -2 epsilon _ set-transition ] each '[ -2 epsilon _ set-transition ] each
H{ { -2 -2 } } >>final-states ; HS{ -2 } clone >>final-states ;
: adjoin-dfa ( transition-table -- start end ) : adjoin-dfa ( transition-table -- start end )
unify-final-state renumber-states box-transitions unify-final-state renumber-states box-transitions
[ start-state>> ] [ start-state>> ]
[ final-states>> keys first ] [ final-states>> members first ]
[ nfa-table get [ transitions>> ] bi@ swap assoc-union! drop ] tri ; [ nfa-table get [ transitions>> ] bi@ swap assoc-union! drop ] tri ;
: ast>dfa ( parse-tree -- minimal-dfa ) : ast>dfa ( parse-tree -- minimal-dfa )

View File

@ -5,6 +5,7 @@ sequences fry quotations math.order math.ranges vectors
unicode.categories regexp.transition-tables words sets hashtables unicode.categories regexp.transition-tables words sets hashtables
combinators.short-circuit unicode.data regexp.ast combinators.short-circuit unicode.data regexp.ast
regexp.classes memoize ; regexp.classes memoize ;
FROM: namespaces => set ;
IN: regexp.nfa IN: regexp.nfa
! This uses unicode.data for ch>upper and ch>lower ! This uses unicode.data for ch>upper and ch>lower
@ -162,6 +163,6 @@ M: with-options nfa-node ( node -- start end )
<transition-table> nfa-table set <transition-table> nfa-table set
nfa-node nfa-node
nfa-table get nfa-table get
swap dup associate >>final-states swap 1array fast-set >>final-states
swap >>start-state swap >>start-state
] with-scope ; ] with-scope ;

View File

@ -27,7 +27,7 @@ ERROR: bad-class name ;
[ [ simple ] keep ] H{ } map>assoc ; [ [ simple ] keep ] H{ } map>assoc ;
MEMO: simple-script-table ( -- table ) MEMO: simple-script-table ( -- table )
script-table interval-values prune simple-table ; script-table interval-values members simple-table ;
MEMO: simple-category-table ( -- table ) MEMO: simple-category-table ( -- table )
categories simple-table ; categories simple-table ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs fry hashtables kernel sequences USING: accessors arrays assocs fry hashtables kernel sequences
vectors locals regexp.classes ; vectors locals regexp.classes sets ;
IN: regexp.transition-tables IN: regexp.transition-tables
TUPLE: transition-table transitions start-state final-states ; TUPLE: transition-table transitions start-state final-states ;
@ -9,7 +9,7 @@ TUPLE: transition-table transitions start-state final-states ;
: <transition-table> ( -- transition-table ) : <transition-table> ( -- transition-table )
transition-table new transition-table new
H{ } clone >>transitions H{ } clone >>transitions
H{ } clone >>final-states ; HS{ } clone >>final-states ;
:: (set-transition) ( from to obj hash -- ) :: (set-transition) ( from to obj hash -- )
from hash at from hash at
@ -27,8 +27,8 @@ TUPLE: transition-table transitions start-state final-states ;
: add-transition ( from to obj transition-table -- ) : add-transition ( from to obj transition-table -- )
transitions>> (add-transition) ; transitions>> (add-transition) ;
: map-set ( assoc quot -- new-assoc ) : map-set ( set quot -- new-set )
'[ drop @ dup ] assoc-map ; inline over [ [ members ] dip map ] dip set-like ; inline
: number-transitions ( transitions numbering -- new-transitions ) : number-transitions ( transitions numbering -- new-transitions )
dup '[ dup '[

View File

@ -8,6 +8,9 @@ io.streams.string io.styles kernel make namespaces prettyprint
prettyprint.backend prettyprint.config prettyprint.custom prettyprint.backend prettyprint.config prettyprint.custom
prettyprint.sections sequences sets sorting strings summary words prettyprint.sections sequences sets sorting strings summary words
words.symbol words.constant words.alias vocabs slots ; words.symbol words.constant words.alias vocabs slots ;
FROM: namespaces => set ;
FROM: classes => members ;
RENAME: members sets => set-members
IN: see IN: see
GENERIC: synopsis* ( defspec -- ) GENERIC: synopsis* ( defspec -- )
@ -237,7 +240,7 @@ PRIVATE>
dup class? [ dup seeing-implementors % ] when dup class? [ dup seeing-implementors % ] when
dup generic? [ dup seeing-methods % ] when dup generic? [ dup seeing-methods % ] when
drop drop
] { } make prune ; ] { } make set-members ;
: see-methods ( word -- ) : see-methods ( word -- )
methods see-all nl ; methods see-all nl ;

View File

@ -47,7 +47,7 @@ SYMBOL: interned
] { } make <interval-map> ; ] { } make <interval-map> ;
: process-interval-file ( ranges -- table ) : process-interval-file ( ranges -- table )
dup values prune interned dup values members interned
[ expand-ranges ] with-variable ; [ expand-ranges ] with-variable ;
: load-interval-file ( filename -- table ) : load-interval-file ( filename -- table )

View File

@ -7,6 +7,7 @@ io.encodings.ascii io.timeouts io.sockets io.sockets.secure io.crlf
kernel logging sequences combinators splitting assocs strings kernel logging sequences combinators splitting assocs strings
math.order math.parser random system calendar summary calendar.format math.order math.parser random system calendar summary calendar.format
accessors sets hashtables base64 debugger classes prettyprint words ; accessors sets hashtables base64 debugger classes prettyprint words ;
FROM: namespaces => set ;
IN: smtp IN: smtp
SYMBOL: smtp-domain SYMBOL: smtp-domain

View File

@ -7,6 +7,7 @@ definitions locals sets hints macros stack-checker.state
stack-checker.visitor stack-checker.errors stack-checker.values stack-checker.visitor stack-checker.errors stack-checker.values
stack-checker.recursive-state stack-checker.dependencies summary ; stack-checker.recursive-state stack-checker.dependencies summary ;
FROM: sequences.private => from-end ; FROM: sequences.private => from-end ;
FROM: namespaces => set ;
IN: stack-checker.backend IN: stack-checker.backend
: push-d ( obj -- ) meta-d push ; : push-d ( obj -- ) meta-d push ;

View File

@ -5,6 +5,7 @@ generic kernel math namespaces sequences words sets
combinators.short-circuit classes.tuple alien.c-types ; combinators.short-circuit classes.tuple alien.c-types ;
FROM: classes.tuple.private => tuple-layout ; FROM: classes.tuple.private => tuple-layout ;
FROM: assocs => change-at ; FROM: assocs => change-at ;
FROM: namespaces => set ;
IN: stack-checker.dependencies IN: stack-checker.dependencies
! Words that the current quotation depends on ! Words that the current quotation depends on

View File

@ -9,6 +9,7 @@ sequences.private generalizations stack-checker.backend
stack-checker.state stack-checker.visitor stack-checker.errors stack-checker.state stack-checker.visitor stack-checker.errors
stack-checker.values stack-checker.recursive-state stack-checker.values stack-checker.recursive-state
stack-checker.dependencies ; stack-checker.dependencies ;
FROM: namespaces => set ;
IN: stack-checker.transforms IN: stack-checker.transforms
: call-transformer ( stack quot -- newquot ) : call-transformer ( stack quot -- newquot )

View File

@ -25,14 +25,14 @@ IN: suffix-arrays.tests
[ { } ] [ { } ]
[ SA{ } "something" swap query ] unit-test [ SA{ } "something" swap query ] unit-test
[ V{ "unit-test" "(unit-test)" } ] [ { "unit-test" "(unit-test)" } ]
[ "suffix-array" get "unit-test" swap query ] unit-test [ "suffix-array" get "unit-test" swap query ] unit-test
[ t ] [ t ]
[ "suffix-array" get "something else" swap query empty? ] unit-test [ "suffix-array" get "something else" swap query empty? ] unit-test
[ V{ "rofl" } ] [ SA{ "rofl" } "r" swap query ] unit-test [ { "rofl" } ] [ SA{ "rofl" } "r" swap query ] unit-test
[ V{ "rofl" } ] [ SA{ "rofl" } "o" swap query ] unit-test [ { "rofl" } ] [ SA{ "rofl" } "o" swap query ] unit-test
[ V{ "rofl" } ] [ SA{ "rofl" } "f" swap query ] unit-test [ { "rofl" } ] [ SA{ "rofl" } "f" swap query ] unit-test
[ V{ "rofl" } ] [ SA{ "rofl" } "l" swap query ] unit-test [ { "rofl" } ] [ SA{ "rofl" } "l" swap query ] unit-test
[ V{ } ] [ SA{ "rofl" } "t" swap query ] unit-test [ { } ] [ SA{ "rofl" } "t" swap query ] unit-test

View File

@ -35,5 +35,5 @@ SYNTAX: SA{ \ } [ >suffix-array ] parse-literal ;
: query ( begin suffix-array -- matches ) : query ( begin suffix-array -- matches )
2dup find-index dup 2dup find-index dup
[ -rot [ from-to ] keep <funky-slice> [ seq>> ] map prune ] [ -rot [ from-to ] keep <funky-slice> [ seq>> ] map members ]
[ 3drop { } ] if ; [ 3drop { } ] if ;

View File

@ -20,6 +20,8 @@ QUALIFIED: source-files
QUALIFIED: source-files.errors QUALIFIED: source-files.errors
QUALIFIED: vocabs QUALIFIED: vocabs
FROM: alien.libraries.private => >deployed-library-path ; FROM: alien.libraries.private => >deployed-library-path ;
FROM: namespaces => set ;
FROM: sets => members ;
IN: tools.deploy.shaker IN: tools.deploy.shaker
! This file is some hairy shit. ! This file is some hairy shit.
@ -506,7 +508,7 @@ SYMBOL: deploy-vocab
: write-vocab-manifest ( vocab-manifest-out -- ) : write-vocab-manifest ( vocab-manifest-out -- )
"Writing vocabulary manifest to " write dup print flush "Writing vocabulary manifest to " write dup print flush
vocabs "VOCABS:" prefix vocabs "VOCABS:" prefix
deploy-libraries get [ libraries get at path>> ] map prune "LIBRARIES:" prefix append deploy-libraries get [ libraries get at path>> ] map members "LIBRARIES:" prefix append
swap utf8 set-file-lines ; swap utf8 set-file-lines ;
: prepare-deploy-libraries ( -- ) : prepare-deploy-libraries ( -- )

View File

@ -5,6 +5,7 @@ io io.styles namespaces assocs kernel.private strings
combinators sorting math.parser vocabs definitions combinators sorting math.parser vocabs definitions
tools.profiler.private tools.crossref continuations generic tools.profiler.private tools.crossref continuations generic
compiler.units compiler.crossref sets classes fry ; compiler.units compiler.crossref sets classes fry ;
FROM: sets => members ;
IN: tools.profiler IN: tools.profiler
: profile ( quot -- ) : profile ( quot -- )
@ -41,7 +42,7 @@ IN: tools.profiler
[ smart-usage [ word? ] filter ] [ smart-usage [ word? ] filter ]
[ generic-call-sites-of keys ] [ generic-call-sites-of keys ]
[ effect-dependencies-of keys ] [ effect-dependencies-of keys ]
tri 3append prune ; tri 3append members ;
: usage-counters ( word -- alist ) : usage-counters ( word -- alist )
profiler-usage counters ; profiler-usage counters ;

View File

@ -2,6 +2,7 @@ USING: accessors ui.gadgets ui.gadgets.packs ui.gadgets.worlds
tools.test namespaces models kernel dlists deques math tools.test namespaces models kernel dlists deques math
math.parser ui sequences hashtables assocs io arrays prettyprint math.parser ui sequences hashtables assocs io arrays prettyprint
io.streams.string math.rectangles ui.gadgets.private sets generic ; io.streams.string math.rectangles ui.gadgets.private sets generic ;
FROM: namespaces => set ;
IN: ui.gadgets.tests IN: ui.gadgets.tests
[ { 300 300 } ] [ { 300 300 } ]
@ -126,16 +127,16 @@ M: mock-gadget ungraft*
] each-integer ; ] each-integer ;
: status-flags ( -- seq ) : status-flags ( -- seq )
{ "g" "1" "2" "3" } [ get graft-state>> ] map prune ; { "g" "1" "2" "3" } [ get graft-state>> ] map members ;
: notify-combo ( ? ? -- ) : notify-combo ( ? ? -- )
nl "===== Combo: " write 2dup 2array . nl nl "===== Combo: " write 2dup 2array . nl
<dlist> \ graft-queue [ <dlist> \ graft-queue [
<mock-gadget> "g" set <mock-gadget> "g" set
[ ] [ add-some-children ] unit-test [ ] [ add-some-children ] unit-test
[ V{ { f f } } ] [ status-flags ] unit-test [ { { f f } } ] [ status-flags ] unit-test
[ ] [ "g" get graft ] unit-test [ ] [ "g" get graft ] unit-test
[ V{ { f t } } ] [ status-flags ] unit-test [ { { f t } } ] [ status-flags ] unit-test
dup [ [ ] [ notify-queued ] unit-test ] when dup [ [ ] [ notify-queued ] unit-test ] when
[ ] [ "g" get clear-gadget ] unit-test [ ] [ "g" get clear-gadget ] unit-test
[ [ t ] [ graft-queue [ front>> ] [ back>> ] bi eq? ] unit-test ] unless [ [ t ] [ graft-queue [ front>> ] [ back>> ] bi eq? ] unit-test ] unless
@ -146,7 +147,7 @@ M: mock-gadget ungraft*
[ { f t } ] [ "3" get graft-state>> ] unit-test [ { f t } ] [ "3" get graft-state>> ] unit-test
[ ] [ graft-queue [ "x" print notify ] slurp-deque ] unit-test [ ] [ graft-queue [ "x" print notify ] slurp-deque ] unit-test
[ ] [ notify-queued ] unit-test [ ] [ notify-queued ] unit-test
[ V{ { t t } } ] [ status-flags ] unit-test [ { { t t } } ] [ status-flags ] unit-test
] with-variable ; ] with-variable ;
{ { f f } { f t } { t f } { t t } } [ notify-combo ] assoc-each { { f f } { f t } { t f } { t t } } [ notify-combo ] assoc-each

View File

@ -5,6 +5,8 @@ namespaces make sequences words strings system hashtables math.parser
math.vectors classes.tuple classes boxes calendar alarms combinators math.vectors classes.tuple classes boxes calendar alarms combinators
sets columns fry deques ui.gadgets ui.gadgets.private ascii sets columns fry deques ui.gadgets ui.gadgets.private ascii
combinators.short-circuit ; combinators.short-circuit ;
FROM: namespaces => set ;
FROM: sets => members ;
IN: ui.gestures IN: ui.gestures
: get-gesture-handler ( gesture gadget -- quot ) : get-gesture-handler ( gesture gadget -- quot )
@ -234,7 +236,7 @@ SYMBOL: drag-timer
: modifier ( mod modifiers -- seq ) : modifier ( mod modifiers -- seq )
[ second swap bitand 0 > ] with filter [ second swap bitand 0 > ] with filter
0 <column> prune [ f ] [ >array ] if-empty ; 0 <column> members [ f ] [ >array ] if-empty ;
: drag-loc ( -- loc ) : drag-loc ( -- loc )
hand-loc get-global hand-click-loc get-global v- ; hand-loc get-global hand-click-loc get-global v- ;

View File

@ -16,6 +16,7 @@ ui.tools.listener.completion ui.tools.listener.popups
ui.tools.listener.history ui.images ui.tools.error-list ui.tools.listener.history ui.images ui.tools.error-list
tools.errors.model ; tools.errors.model ;
FROM: source-files.errors => all-errors ; FROM: source-files.errors => all-errors ;
FROM: namespaces => set ;
IN: ui.tools.listener IN: ui.tools.listener
! If waiting is t, we're waiting for user input, and invoking ! If waiting is t, we're waiting for user input, and invoking

View File

@ -138,7 +138,7 @@ M: world ungraft*
layout-queue [ layout-queue [
dup layout find-world [ , ] when* dup layout find-world [ , ] when*
] slurp-deque ] slurp-deque
] { } make prune ; ] { } make members ;
: redraw-worlds ( seq -- ) : redraw-worlds ( seq -- )
[ dup update-hand draw-world ] each ; [ dup update-hand draw-world ] each ;

View File

@ -6,6 +6,7 @@ math.parser hash2 math.order byte-arrays namespaces
compiler.units parser io.encodings.ascii values interval-maps compiler.units parser io.encodings.ascii values interval-maps
ascii sets combinators locals math.ranges sorting make ascii sets combinators locals math.ranges sorting make
strings.parser io.encodings.utf8 memoize simple-flat-file ; strings.parser io.encodings.utf8 memoize simple-flat-file ;
FROM: namespaces => set ;
IN: unicode.data IN: unicode.data
<PRIVATE <PRIVATE
@ -183,7 +184,7 @@ C: <code-point> code-point
] assoc-map ; ] assoc-map ;
: properties>intervals ( properties -- assoc[str,interval] ) : properties>intervals ( properties -- assoc[str,interval] )
dup values prune [ f ] H{ } map>assoc dup values members [ f ] H{ } map>assoc
[ [ push-at ] curry assoc-each ] keep [ [ push-at ] curry assoc-each ] keep
[ <interval-set> ] assoc-map ; [ <interval-set> ] assoc-map ;

View File

@ -65,8 +65,8 @@ PRIVATE>
#! Hack. #! Hack.
[ vocab-prefix? ] partition [ vocab-prefix? ] partition
[ [
[ vocab-name ] map unique [ vocab-name ] map fast-set
'[ name>> _ key? not ] filter '[ name>> _ in? not ] filter
convert-prefixes convert-prefixes
] keep ] keep
append ; append ;

View File

@ -73,7 +73,7 @@ M: vocab-link summary vocab-summary ;
dup vocab-tags-path set-vocab-file-contents ; dup vocab-tags-path set-vocab-file-contents ;
: add-vocab-tags ( tags vocab -- ) : add-vocab-tags ( tags vocab -- )
[ vocab-tags append prune ] keep set-vocab-tags ; [ vocab-tags append members ] keep set-vocab-tags ;
: remove-vocab-tags ( tags vocab -- ) : remove-vocab-tags ( tags vocab -- )
[ vocab-tags swap diff ] keep set-vocab-tags ; [ vocab-tags swap diff ] keep set-vocab-tags ;

View File

@ -39,7 +39,7 @@ TR: convert-separators "/\\" ".." ;
: monitor-thread ( -- ) : monitor-thread ( -- )
[ [
[ [
vocab-roots get prune [ add-monitor-for-path ] each vocab-roots get [ add-monitor-for-path ] each
H{ } clone changed-vocabs set-global H{ } clone changed-vocabs set-global
vocabs [ changed-vocab ] each vocabs [ changed-vocab ] each

View File

@ -3,6 +3,7 @@
USING: accessors assocs checksums checksums.crc32 USING: accessors assocs checksums checksums.crc32
io.encodings.utf8 io.files kernel namespaces sequences sets io.encodings.utf8 io.files kernel namespaces sequences sets
source-files vocabs vocabs.errors vocabs.loader ; source-files vocabs vocabs.errors vocabs.loader ;
FROM: namespaces => set ;
IN: vocabs.refresh IN: vocabs.refresh
: source-modified? ( path -- ? ) : source-modified? ( path -- ? )
@ -81,11 +82,11 @@ SYMBOL: modified-docs
[ [ vocab f >>docs-loaded? drop ] each ] bi* [ [ vocab f >>docs-loaded? drop ] each ] bi*
] ]
[ [
append prune union
[ unchanged-vocabs ] [ unchanged-vocabs ]
[ require-all load-failures. ] bi [ require-all load-failures. ] bi
] 2bi ; ] 2bi ;
: refresh ( prefix -- ) to-refresh do-refresh ; : refresh ( prefix -- ) to-refresh do-refresh ;
: refresh-all ( -- ) "" refresh ; : refresh-all ( -- ) "" refresh ;

View File

@ -4,6 +4,7 @@ USING: kernel namespaces xml.tokenize xml.state xml.name
xml.data accessors arrays make xml.char-classes fry assocs sequences xml.data accessors arrays make xml.char-classes fry assocs sequences
math xml.errors sets combinators io.encodings io.encodings.iana math xml.errors sets combinators io.encodings io.encodings.iana
unicode.case xml.dtd strings xml.entities unicode.categories ; unicode.case xml.dtd strings xml.entities unicode.categories ;
FROM: namespaces => set ;
IN: xml.elements IN: xml.elements
: take-interpolated ( quot -- interpolated ) : take-interpolated ( quot -- interpolated )

View File

@ -32,7 +32,7 @@ M: keyword-map >alist
assoc>> >alist ; assoc>> >alist ;
: (keyword-map-no-word-sep) ( assoc -- str ) : (keyword-map-no-word-sep) ( assoc -- str )
keys concat [ alpha? not ] filter prune natural-sort ; keys combine [ alpha? not ] filter natural-sort ;
: keyword-map-no-word-sep* ( keyword-map -- str ) : keyword-map-no-word-sep* ( keyword-map -- str )
dup no-word-sep>> [ ] [ dup no-word-sep>> [ ] [

View File

@ -1,6 +1,7 @@
USING: accessors alien alien.accessors alien.syntax byte-arrays arrays USING: accessors alien alien.accessors alien.syntax byte-arrays arrays
kernel kernel.private namespaces tools.test sequences libc math kernel kernel.private namespaces tools.test sequences libc math
system prettyprint layouts alien.libraries sets ; system prettyprint layouts alien.libraries sets ;
FROM: namespaces => set ;
IN: alien.tests IN: alien.tests
[ t ] [ -1 <alien> alien-address 0 > ] unit-test [ t ] [ -1 <alien> alien-address 0 > ] unit-test
@ -83,4 +84,4 @@ f initialize-test set-global
[ 7575 ] [ initialize-test [ 7575 ] initialize-alien ] unit-test [ 7575 ] [ initialize-test [ 7575 ] initialize-alien ] unit-test
[ V{ BAD-ALIEN } ] [ { BAD-ALIEN BAD-ALIEN BAD-ALIEN } prune ] unit-test [ { BAD-ALIEN } ] [ { BAD-ALIEN BAD-ALIEN BAD-ALIEN } members ] unit-test

View File

@ -29,6 +29,7 @@ IN: bootstrap.syntax
"HEX:" "HEX:"
"HOOK:" "HOOK:"
"H{" "H{"
"HS{"
"IN:" "IN:"
"INSTANCE:" "INSTANCE:"
"M:" "M:"

View File

@ -3,6 +3,8 @@
USING: kernel classes classes.private combinators accessors USING: kernel classes classes.private combinators accessors
sequences arrays vectors assocs namespaces words sorting layouts sequences arrays vectors assocs namespaces words sorting layouts
math hashtables kernel.private sets math.order ; math hashtables kernel.private sets math.order ;
FROM: classes => members ;
RENAME: members sets => set-members
IN: classes.algebra IN: classes.algebra
<PRIVATE <PRIVATE
@ -10,13 +12,14 @@ IN: classes.algebra
TUPLE: anonymous-union { members read-only } ; TUPLE: anonymous-union { members read-only } ;
: <anonymous-union> ( members -- class ) : <anonymous-union> ( members -- class )
[ null eq? not ] filter prune [ null eq? not ] filter set-members
dup length 1 = [ first ] [ anonymous-union boa ] if ; dup length 1 = [ first ] [ anonymous-union boa ] if ;
TUPLE: anonymous-intersection { participants read-only } ; TUPLE: anonymous-intersection { participants read-only } ;
: <anonymous-intersection> ( participants -- class ) : <anonymous-intersection> ( participants -- class )
prune dup length 1 = [ first ] [ anonymous-intersection boa ] if ; set-members dup length 1 =
[ first ] [ anonymous-intersection boa ] if ;
TUPLE: anonymous-complement { class read-only } ; TUPLE: anonymous-complement { class read-only } ;

View File

@ -4,6 +4,7 @@ USING: accessors arrays definitions assocs kernel kernel.private
slots.private namespaces make sequences strings words words.symbol slots.private namespaces make sequences strings words words.symbol
vectors math quotations combinators sorting effects graphs vectors math quotations combinators sorting effects graphs
vocabs sets ; vocabs sets ;
FROM: namespaces => set ;
IN: classes IN: classes
ERROR: bad-inheritance class superclass ; ERROR: bad-inheritance class superclass ;

View File

@ -147,7 +147,7 @@ ERROR: no-case object ;
: contiguous-range? ( keys -- ? ) : contiguous-range? ( keys -- ? )
dup [ fixnum? ] all? [ dup [ fixnum? ] all? [
dup all-unique? [ dup all-unique? [
[ prune length ] [ length ]
[ [ supremum ] [ infimum ] bi - ] [ [ supremum ] [ infimum ] bi - ]
bi - 1 = bi - 1 =
] [ drop f ] if ] [ drop f ] if

View File

@ -4,6 +4,7 @@ USING: accessors arrays kernel continuations assocs namespaces
sequences words vocabs definitions hashtables init sets math sequences words vocabs definitions hashtables init sets math
math.order classes classes.private classes.algebra classes.tuple math.order classes classes.private classes.algebra classes.tuple
classes.tuple.private generic source-files.errors kernel.private ; classes.tuple.private generic source-files.errors kernel.private ;
FROM: namespaces => set ;
IN: compiler.units IN: compiler.units
SYMBOL: old-definitions SYMBOL: old-definitions

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors continuations kernel namespaces make USING: accessors continuations kernel namespaces make
sequences vectors sets assocs init math ; sequences vectors sets assocs init math ;
FROM: namespaces => set ;
IN: destructors IN: destructors
SYMBOL: disposables SYMBOL: disposables

View File

@ -4,6 +4,7 @@ USING: accessors words kernel sequences namespaces make assocs
hashtables definitions kernel.private classes classes.private hashtables definitions kernel.private classes classes.private
classes.algebra quotations arrays vocabs effects combinators classes.algebra quotations arrays vocabs effects combinators
sets ; sets ;
FROM: namespaces => set ;
IN: generic IN: generic
! Method combination protocol ! Method combination protocol

View File

@ -5,6 +5,7 @@ quotations stack-checker vectors growable hashtables sbufs
prettyprint byte-vectors bit-vectors specialized-vectors prettyprint byte-vectors bit-vectors specialized-vectors
definitions generic sets graphs assocs grouping see eval ; definitions generic sets graphs assocs grouping see eval ;
QUALIFIED-WITH: alien.c-types c QUALIFIED-WITH: alien.c-types c
FROM: namespaces => set ;
SPECIALIZED-VECTOR: c:double SPECIALIZED-VECTOR: c:double
IN: generic.single.tests IN: generic.single.tests

View File

@ -0,0 +1,18 @@
USING: help.markup help.syntax sequences ;
IN: hash-sets
ARTICLE: "hash-sets" "Hash sets"
"The " { $vocab-link "hash-sets" } " vocabulary implements hashtable-backed sets. These are of the class:"
{ $subsection hash-set }
"They can be instantiated with the word"
{ $subsection <hash-set> }
"The syntax for hash sets is described in " { $link "syntax-hash-sets" } "." ;
ABOUT: "hash-sets"
HELP: hash-set
{ $class-description "The class of hashtable-based sets. These implement the " { $link "sets" } "." } ;
HELP: <hash-set>
{ $values { "members" sequence } { "hash-set" hash-set } }
{ $description "Creates a new hash set with the given members." } ;

View File

@ -0,0 +1,33 @@
! Copyright (C) 2010 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: sets tools.test kernel sorting prettyprint hash-sets ;
IN: hash-sets.tests
[ { 1 2 3 } ] [ HS{ 1 2 3 } members natural-sort ] unit-test
[ "HS{ 1 2 3 4 }" ] [ HS{ 1 2 3 4 } unparse ] unit-test
[ t ] [ 1 HS{ 0 1 2 } in? ] unit-test
[ f ] [ 3 HS{ 0 1 2 } in? ] unit-test
[ HS{ 1 2 3 } ] [ 3 HS{ 1 2 } clone [ adjoin ] keep ] unit-test
[ HS{ 1 2 } ] [ 2 HS{ 1 2 } clone [ adjoin ] keep ] unit-test
[ HS{ 1 2 3 } ] [ 4 HS{ 1 2 3 } clone [ delete ] keep ] unit-test
[ HS{ 1 2 } ] [ 3 HS{ 1 2 3 } clone [ delete ] keep ] unit-test
[ HS{ 1 2 } ] [ HS{ 1 2 } fast-set ] unit-test
[ { 1 2 } ] [ HS{ 1 2 } members natural-sort ] unit-test
[ HS{ 1 2 3 4 } ] [ HS{ 1 2 3 } HS{ 2 3 4 } union ] unit-test
[ HS{ 2 3 } ] [ HS{ 1 2 3 } HS{ 2 3 4 } intersect ] unit-test
[ t ] [ HS{ 1 2 3 } HS{ 2 3 4 } intersects? ] unit-test
[ f ] [ HS{ 1 } HS{ 2 3 4 } intersects? ] unit-test
[ f ] [ HS{ 1 } HS{ 2 3 4 } subset? ] unit-test
[ f ] [ HS{ 1 2 3 } HS{ 2 3 4 } subset? ] unit-test
[ t ] [ HS{ 2 3 } HS{ 2 3 4 } subset? ] unit-test
[ t ] [ HS{ } HS{ 2 3 4 } subset? ] unit-test
[ HS{ 1 } ] [ HS{ 1 2 3 } HS{ 2 3 4 } diff ] unit-test
[ t ] [ HS{ 1 2 3 } HS{ 2 1 3 } set= ] unit-test
[ t ] [ HS{ 1 2 3 } HS{ 2 1 3 } = ] unit-test
[ f ] [ HS{ 2 3 } HS{ 2 1 3 } set= ] unit-test
[ f ] [ HS{ 1 2 3 } HS{ 2 3 } set= ] unit-test
[ HS{ 1 2 } HS{ 1 2 3 } ] [ HS{ 1 2 } clone dup clone [ 3 swap adjoin ] keep ] unit-test

View File

@ -0,0 +1,28 @@
! Copyright (C) 2010 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs hashtables kernel sets
sequences parser ;
QUALIFIED: sets
IN: hash-sets
! In a better implementation, less memory would be used
TUPLE: hash-set { table hashtable read-only } ;
: <hash-set> ( members -- hash-set )
[ dup ] H{ } map>assoc hash-set boa ;
INSTANCE: hash-set set
M: hash-set in? table>> key? ; inline
M: hash-set adjoin table>> dupd set-at ; inline
M: hash-set delete table>> delete-at ; inline
M: hash-set members table>> keys ; inline
M: hash-set set-like
drop dup hash-set? [ members <hash-set> ] unless ;
M: hash-set clone
table>> clone hash-set boa ;
M: sequence fast-set <hash-set> ;
M: f fast-set drop H{ } clone hash-set boa ;
M: sequence duplicates
HS{ } clone [ [ in? ] [ adjoin ] 2bi ] curry filter ;

View File

@ -1,42 +1,71 @@
USING: assocs hashtables help.markup help.syntax kernel USING: assocs hashtables help.markup help.syntax kernel
quotations sequences ; quotations sequences vectors ;
IN: sets IN: sets
ARTICLE: "sets" "Set-theoretic operations on sequences" ARTICLE: "sets" "Sets"
"Set-theoretic operations on sequences are defined on the " { $vocab-link "sets" } " vocabulary. All of these operations use hashtables internally to achieve linear running time." "A set is an unordered list of elements. Words for working with sets are in the " { $vocab-link "sets" } " vocabulary."
$nl "All sets are instances of a mixin class:"
"Remove duplicates:"
{ $subsections prune }
"Test for duplicates:"
{ $subsections { $subsections
all-unique? set
duplicates set?
} }
"Set operations on sequences:" { $subsections "set-operations" "set-implementations" } ;
ABOUT: "sets"
ARTICLE: "set-operations" "Operations on sets"
"To test if an object is a member of a set:"
{ $subsection member? }
"All sets can be represented as a sequence, without duplicates, of their members:"
{ $subsection members }
"Sets can have members added or removed destructively:"
{ $subsections
adjoin
delete
}
"Basic mathematical operations, which any type of set may override for efficiency:"
{ $subsections { $subsections
diff diff
intersect intersect
union union
} }
"Set-theoretic predicates:" "Mathematical predicates on sets, which may be overridden for efficiency:"
{ $subsections { $subsections
intersects? intersects?
subset? subset?
set= set=
} }
"A word used to implement the above:" "An optional generic word for creating sets of the same class as a given set:"
{ $subsections unique } { $subsection set-like }
"Adding elements to sets:" "An optional generic word for creating a set with a fast lookup operation, if the set itself has a slow lookup operation:"
{ $subsection fast-set }
"For set types that allow duplicates, like sequence sets, some additional words test for duplication:"
{ $subsections { $subsections
adjoin all-unique?
} duplicates
{ $see-also member? member-eq? any? all? "assocs-sets" } ; } ;
ABOUT: "sets" ARTICLE: "set-implementations" "Set implementations"
"There are several implementations of sets in the Factor library. More can be added if they implement the words of the set protocol, the basic set operations."
{ $subsections
"sequence-sets"
"hash-sets"
"bit-sets"
} ;
ARTICLE: "sequence-sets" "Sequences as sets"
"Any sequence can be used as a set. The members of this set are the elements of the sequence. Calling the word " { $link members } " on a sequence returns a copy of the sequence with only one listing of each member. Destructive operations " { $link adjoin } " and " { $link delete } " only work properly on growable sequences like " { $link vector } "s."
$nl
"Care must be taken in writing efficient code using sequence sets. Testing for membership with " { $link in? } ", as well as the destructive set operations, take time proportional to the size of the sequence. Another representation, like " { $link "hash-sets" } ", would take constant time for membership tests. But binary operations like " { $link union } "are asymptotically optimal, taking time proportional to the sum of the size of the inputs."
$nl
"As one particlar example, " { $link POSTPONE: f } " is a representation of the empty set, as it represents the empty sequence." ;
HELP: set
{ $class-description "The class of all sets. Custom implementations of the set protocol should be declared as instances of this mixin for all set implementation to work correctly." } ;
HELP: adjoin HELP: adjoin
{ $values { "elt" object } { "seq" "a resizable mutable sequence" } } { $values { "elt" object } { "set" set } }
{ $description "Removes all elements equal to " { $snippet "elt" } ", and adds " { $snippet "elt" } " at the end of the sequence." } { $description "Destructively adds " { $snippet "elt" } " to " { $snippet "set" } ". For sequences, this guarantees that this element is not duplicated, and that it is at the end of the sequence." $nl "Each mutable set type is expected to implement a method on this generic word." }
{ $examples { $examples
{ $example { $example
"USING: namespaces prettyprint sets ;" "USING: namespaces prettyprint sets ;"
@ -47,48 +76,36 @@ HELP: adjoin
"V{ \"beans\" \"cheese\" \"nachos\" \"salsa\" }" "V{ \"beans\" \"cheese\" \"nachos\" \"salsa\" }"
} }
} }
{ $side-effects "seq" } ; { $side-effects "set" } ;
HELP: conjoin HELP: delete
{ $values { "elt" object } { "assoc" assoc } } { $values { "elt" object } { "set" set } }
{ $description "Stores a key/value pair, both equal to " { $snippet "elt" } ", into the assoc." } { $description "Destructively removes " { $snippet "elt" } " from " { $snippet "set" } ". If the element is not present, this does nothing." $nl "Each mutable set type is expected to implement a method on this generic word." }
{ $examples { $side-effects "set" } ;
{ $example
"USING: kernel prettyprint sets ;" HELP: members
"H{ } clone 1 over conjoin ." { $values { "set" set } { "seq" sequence } }
"H{ { 1 1 } }" { $description "Creates a sequence with a single copy of each member of the set." $nl "Each set type is expected to implement a method on this generic word." } ;
}
} HELP: in?
{ $values { "elt" object } { "set" set } { "?" "a boolean" } }
{ $description "Tests whether the element is a member of the set." $nl "Each set type is expected to implement a method on this generic word as part of the set protocol." } ;
HELP: adjoin-at
{ $values { "value" object } { "key" object } { "assoc" assoc } }
{ $description "Adds " { $snippet "value" } " to the set stored at " { $snippet "key" } " of " { $snippet "assoc" } "." }
{ $side-effects "assoc" } ; { $side-effects "assoc" } ;
HELP: conjoin-at
{ $values { "value" object } { "key" object } { "assoc" assoc } }
{ $description "Adds " { $snippet "value" } " to the set stored at " { $snippet "key" } " of " { $snippet "assoc" } "." } ;
HELP: unique
{ $values { "seq" "a sequence" } { "assoc" assoc } }
{ $description "Outputs a new assoc where the keys and values are equal." }
{ $examples
{ $example "USING: sets prettyprint ;" "{ 1 1 2 2 3 3 } unique ." "H{ { 1 1 } { 2 2 } { 3 3 } }" }
} ;
HELP: prune
{ $values { "seq" "a sequence" } { "newseq" "a sequence" } }
{ $description "Outputs a new sequence with each distinct element of " { $snippet "seq" } " appearing only once. Elements are compared for equality using " { $link = } " and elements are ordered according to their position in " { $snippet "seq" } "." }
{ $examples
{ $example "USING: sets prettyprint ;" "{ 1 1 t 3 t } prune ." "V{ 1 t 3 }" }
} ;
HELP: duplicates HELP: duplicates
{ $values { "seq" "a sequence" } { "newseq" "a sequence" } } { $values { "set" set } { "seq" sequence } }
{ $description "Outputs a new sequence consisting of elements which occur more than once in " { $snippet "seq" } "." } { $description "Outputs a sequence consisting of elements which occur more than once in " { $snippet "set" } "." }
{ $examples { $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 1 2 1 } duplicates ." "{ 1 2 1 }" } { $example "USING: sets prettyprint ;" "{ 1 2 3 1 2 1 } duplicates ." "{ 2 1 2 1 }" }
} ; } ;
HELP: all-unique? HELP: all-unique?
{ $values { "seq" sequence } { "?" "a boolean" } } { $values { "set" set } { "?" "a boolean" } }
{ $description "Tests whether a sequence contains any repeated elements." } { $description "Tests whether a set contains any repeated elements." }
{ $example { $example
"USING: sets prettyprint ;" "USING: sets prettyprint ;"
"{ 0 1 1 2 3 5 } all-unique? ." "{ 0 1 1 2 3 5 } all-unique? ."
@ -96,41 +113,44 @@ HELP: all-unique?
} ; } ;
HELP: diff HELP: diff
{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } } { $values { "set1" set } { "set2" set } { "set" set } }
{ $description "Outputs a sequence consisting of elements present in " { $snippet "seq1" } " but not " { $snippet "seq2" } ", comparing elements for equality." { $description "Outputs a set consisting of elements present in " { $snippet "set1" } " but not " { $snippet "set2" } ", comparing elements for equality."
"This word has a default definition which works for all sets, but set implementations may override the default for efficiency."
} { $examples } { $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } diff ." "{ 1 }" } { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } diff ." "{ 1 }" }
} ; } ;
HELP: intersect HELP: intersect
{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } } { $values { "set1" set } { "set2" set } { "set" set } }
{ $description "Outputs a sequence consisting of elements present in both " { $snippet "seq1" } " and " { $snippet "seq2" } "." } { $description "Outputs a set consisting of elements present in both " { $snippet "set1" } " and " { $snippet "set2" } "."
"This word has a default definition which works for all sets, but set implementations may override the default for efficiency." }
{ $examples { $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } intersect ." "{ 2 3 }" } { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } intersect ." "{ 2 3 }" }
} ; } ;
HELP: union HELP: union
{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } } { $values { "set1" set } { "set2" set } { "set" set } }
{ $description "Outputs a sequence consisting of elements present in " { $snippet "seq1" } " and " { $snippet "seq2" } " which does not contain duplicate values." } { $description "Outputs a set consisting of elements present in either " { $snippet "set1" } " or " { $snippet "set2" } " which does not contain duplicate values."
"This word has a default definition which works for all sets, but set implementations may override the default for efficiency." }
{ $examples { $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } union ." "V{ 1 2 3 4 }" } { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } union ." "{ 1 2 3 4 }" }
} ; } ;
{ diff intersect union } related-words { diff intersect union } related-words
HELP: intersects? HELP: intersects?
{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } } { $values { "set1" set } { "set2" set } { "?" "a boolean" } }
{ $description "Tests if " { $snippet "seq1" } " and " { $snippet "seq2" } " have any elements in common." } { $description "Tests if " { $snippet "set1" } " and " { $snippet "set2" } " have any elements in common." }
{ $notes "If one of the sequences is empty, the result is always " { $link f } "." } ; { $notes "If one of the sets is empty, the result is always " { $link f } "." } ;
HELP: subset? HELP: subset?
{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } } { $values { "set1" set } { "set2" set } { "?" "a boolean" } }
{ $description "Tests if every element of " { $snippet "seq1" } " is contained in " { $snippet "seq2" } "." } { $description "Tests if every element of " { $snippet "set1" } " is contained in " { $snippet "set2" } "." }
{ $notes "If " { $snippet "seq1" } " is empty, the result is always " { $link t } "." } ; { $notes "If " { $snippet "set1" } " is empty, the result is always " { $link t } "." } ;
HELP: set= HELP: set=
{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } } { $values { "set1" set } { "set2" set } { "?" "a boolean" } }
{ $description "Tests if both sequences contain the same elements, disregrading order and duplicates." } ; { $description "Tests if both sets contain the same elements, disregrading order and duplicates." } ;
HELP: gather HELP: gather
{ $values { $values
@ -138,3 +158,10 @@ HELP: gather
{ "newseq" sequence } } { "newseq" sequence } }
{ $description "Maps a quotation onto a sequence, concatenates the results of the mapping, and removes duplicates." } ; { $description "Maps a quotation onto a sequence, concatenates the results of the mapping, and removes duplicates." } ;
HELP: set-like
{ $values { "set" set } { "exemplar" set } { "set'" set } }
{ $description "If the conversion is defined for the exemplar, converts the set into a set of the exemplar's class. This is not guaranteed to create a new set, for example if the input set and exemplar are of the same class." $nl
"Set implementations may optionally implement a method on this generic word. The default implementation returns its input set." }
{ $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 } HS{ } set-like ." "HS{ 1 2 3 }" }
} ;

View File

@ -1,26 +1,16 @@
USING: kernel sets tools.test ; ! Copyright (C) 2010 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: sets tools.test kernel prettyprint hash-sets sorting ;
IN: sets.tests IN: sets.tests
[ f ] [ { 0 1 1 2 3 5 } all-unique? ] unit-test
[ t ] [ { 0 1 2 3 4 5 } all-unique? ] unit-test
[ V{ 1 2 3 } ] [ { 1 2 2 3 3 } prune ] unit-test
[ V{ 3 2 1 } ] [ { 3 3 2 2 1 } prune ] unit-test
[ { } ] [ { } { } intersect ] unit-test [ { } ] [ { } { } intersect ] unit-test
[ { 2 3 } ] [ { 1 2 3 } { 2 3 4 } intersect ] unit-test [ { 2 3 } ] [ { 1 2 3 } { 2 3 4 } intersect ] unit-test
[ { } ] [ { } { } diff ] unit-test [ { } ] [ { } { } diff ] unit-test
[ { 1 } ] [ { 1 2 3 } { 2 3 4 } diff ] unit-test [ { 1 } ] [ { 1 2 3 } { 2 3 4 } diff ] unit-test
[ V{ } ] [ { } { } union ] unit-test [ { } ] [ { } { } union ] unit-test
[ V{ 1 2 3 4 } ] [ { 1 2 3 } { 2 3 4 } union ] unit-test [ { 1 2 3 4 } ] [ { 1 2 3 } { 2 3 4 } union ] unit-test
[ V{ 1 2 3 } ]
[ 3 V{ 1 2 } clone [ adjoin ] keep ] unit-test
[ V{ 1 2 3 } ]
[ 3 V{ 1 3 2 } clone [ adjoin ] keep ] unit-test
[ t ] [ { 1 2 } { 1 3 } intersects? ] unit-test [ t ] [ { 1 2 } { 1 3 } intersects? ] unit-test
@ -30,3 +20,34 @@ IN: sets.tests
[ f ] [ { 1 } { } intersects? ] unit-test [ f ] [ { 1 } { } intersects? ] unit-test
[ t ] [ 4 { 2 4 5 } in? ] unit-test
[ f ] [ 1 { 2 4 5 } in? ] unit-test
[ V{ 1 2 3 } ] [ 3 V{ 1 2 } clone [ adjoin ] keep ] unit-test
[ V{ 1 2 } ] [ 2 V{ 1 2 } clone [ adjoin ] keep ] unit-test
[ V{ 1 2 } ] [ 3 V{ 1 2 } clone [ delete ] keep ] unit-test
[ V{ 2 } ] [ 1 V{ 1 2 } clone [ delete ] keep ] unit-test
[ t ] [ { 1 2 3 } { 2 1 3 } set= ] unit-test
[ f ] [ { 2 3 } { 1 2 3 } set= ] unit-test
[ f ] [ { 1 2 3 } { 2 3 } set= ] unit-test
[ { 1 } ] [ { 1 } members ] unit-test
[ { 1 2 3 } ] [ { 1 1 1 2 2 3 3 3 3 3 } dup set-like natural-sort ] unit-test
[ { 1 2 3 } ] [ HS{ 1 2 3 } { } set-like natural-sort ] unit-test
[ HS{ 1 2 3 } ] [ { 1 2 3 } fast-set ] unit-test
[ { 1 2 3 } ] [ { { 1 } { 2 } { 1 3 } } combine ] unit-test
[ f ] [ { 0 1 1 2 3 5 } all-unique? ] unit-test
[ t ] [ { 0 1 2 3 4 5 } all-unique? ] unit-test
[ { 1 2 3 } ] [ { 1 2 2 3 3 } { } set-like ] unit-test
[ { 3 2 1 } ] [ { 3 3 2 2 1 } { } set-like ] unit-test
[ { 2 1 2 1 } ] [ { 1 2 3 2 1 2 1 } duplicates ] unit-test
[ f ] [ HS{ 1 2 3 1 2 1 } duplicates ] unit-test
[ H{ { 3 HS{ 1 2 } } } ] [ H{ } clone 1 3 pick adjoin-at 2 3 pick adjoin-at ] unit-test

View File

@ -1,59 +1,113 @@
! Copyright (C) 2008, 2009 Slava Pestov, Doug Coleman. ! Copyright (C) 2010 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs hashtables kernel sequences vectors ; USING: accessors assocs hashtables kernel vectors
math sequences ;
IN: sets IN: sets
: adjoin ( elt seq -- ) [ remove! drop ] [ push ] 2bi ; ! Set protocol
MIXIN: set
GENERIC: adjoin ( elt set -- )
GENERIC: in? ( elt set -- ? )
GENERIC: delete ( elt set -- )
GENERIC: set-like ( set exemplar -- set' )
GENERIC: fast-set ( set -- set' )
GENERIC: members ( set -- sequence )
GENERIC: union ( set1 set2 -- set )
GENERIC: intersect ( set1 set2 -- set )
GENERIC: intersects? ( set1 set2 -- ? )
GENERIC: diff ( set1 set2 -- set )
GENERIC: subset? ( set1 set2 -- ? )
GENERIC: set= ( set1 set2 -- ? )
GENERIC: duplicates ( set -- seq )
GENERIC: all-unique? ( set -- ? )
: conjoin ( elt assoc -- ) dupd set-at ; ! Defaults for some methods.
! Override them for efficiency
: conjoin-at ( value key assoc -- ) M: set set-like drop ; inline
[ dupd ?set-at ] change-at ;
: (prune) ( elt hash vec -- ) M: set union
3dup drop key? [ 3drop ] [ [ [ members ] bi@ append ] keep set-like ;
[ drop conjoin ] [ nip push ] 3bi
] if ; inline
: prune ( seq -- newseq )
[ ] [ length <hashtable> ] [ length <vector> ] tri
[ [ (prune) ] 2curry each ] keep ;
: duplicates ( seq -- newseq )
H{ } clone [ [ key? ] [ conjoin ] 2bi ] curry filter ;
: gather ( seq quot -- newseq )
map concat prune ; inline
: unique ( seq -- assoc )
[ dup ] H{ } map>assoc ;
: (all-unique?) ( elt hash -- ? )
2dup key? [ 2drop f ] [ conjoin t ] if ;
: all-unique? ( seq -- ? )
dup length <hashtable> [ (all-unique?) ] curry all? ;
<PRIVATE <PRIVATE
: tester ( seq -- quot ) unique [ key? ] curry ; inline : tester ( set -- quot )
fast-set [ in? ] curry ; inline
: sequence/tester ( set1 set2 -- set1' quot )
[ members ] [ tester ] bi* ; inline
PRIVATE> PRIVATE>
: intersect ( seq1 seq2 -- newseq ) M: set intersect
tester filter ; [ sequence/tester filter ] keep set-like ;
: intersects? ( seq1 seq2 -- ? ) M: set diff
tester any? ; [ sequence/tester [ not ] compose filter ] keep set-like ;
: diff ( seq1 seq2 -- newseq ) M: set intersects?
tester [ not ] compose filter ; sequence/tester any? ;
: union ( seq1 seq2 -- newseq ) M: set subset?
append prune ; sequence/tester all? ;
M: set set=
2dup subset? [ swap subset? ] [ 2drop f ] if ;
: subset? ( seq1 seq2 -- ? ) M: set fast-set ;
tester all? ;
: set= ( seq1 seq2 -- ? ) M: set duplicates drop f ;
[ unique ] bi@ = ;
M: set all-unique? drop t ;
<PRIVATE
: (pruned) ( elt hash vec -- )
3dup drop in? [ 3drop ] [
[ drop adjoin ] [ nip push ] 3bi
] if ; inline
: pruned ( seq -- newseq )
[ f fast-set ] [ length <vector> ] bi
[ [ (pruned) ] 2curry each ] keep ;
PRIVATE>
! Sequences are sets
INSTANCE: sequence set
M: sequence in?
member? ; inline
M: sequence adjoin
[ delete ] [ push ] 2bi ;
M: sequence delete
remove! drop ; inline
M: sequence set-like
[ members ] dip like ;
M: sequence members
[ pruned ] keep like ;
M: sequence all-unique?
dup pruned sequence= ;
: combine ( sets -- set )
f [ union ] reduce ;
: gather ( seq quot -- newseq )
map concat members ; inline
: adjoin-at ( value key assoc -- )
[ [ f fast-set ] unless* [ adjoin ] keep ] change-at ;
! Temporarily for compatibility
: unique ( seq -- assoc )
[ dup ] H{ } map>assoc ;
: conjoin ( elt assoc -- )
dupd set-at ;
: conjoin-at ( value key assoc -- )
[ dupd ?set-at ] change-at ;

View File

@ -189,6 +189,10 @@ ARTICLE: "syntax-hashtables" "Hashtable syntax"
{ $subsections POSTPONE: H{ } { $subsections POSTPONE: H{ }
"Hashtables are documented in " { $link "hashtables" } "." ; "Hashtables are documented in " { $link "hashtables" } "." ;
ARTICLE: "syntax-hash-sets" "Hash set syntax"
{ $subsections POSTPONE: HS{ }
"Hashtables are documented in " { $link "hash-sets" } "." ;
ARTICLE: "syntax-tuples" "Tuple syntax" ARTICLE: "syntax-tuples" "Tuple syntax"
{ $subsections POSTPONE: T{ } { $subsections POSTPONE: T{ }
"Tuples are documented in " { $link "tuples" } "." ; "Tuples are documented in " { $link "tuples" } "." ;
@ -229,6 +233,7 @@ $nl
"syntax-vectors" "syntax-vectors"
"syntax-sbufs" "syntax-sbufs"
"syntax-hashtables" "syntax-hashtables"
"syntax-hash-sets"
"syntax-tuples" "syntax-tuples"
"syntax-pathnames" "syntax-pathnames"
"syntax-effects" "syntax-effects"
@ -330,7 +335,7 @@ HELP: }
$nl $nl
"Parsing words can use this word as a generic end delimiter." } ; "Parsing words can use this word as a generic end delimiter." } ;
{ POSTPONE: { POSTPONE: V{ POSTPONE: H{ POSTPONE: C{ POSTPONE: T{ POSTPONE: W{ POSTPONE: } } related-words { POSTPONE: { POSTPONE: V{ POSTPONE: H{ POSTPONE: HS{ POSTPONE: C{ POSTPONE: T{ POSTPONE: W{ POSTPONE: } } related-words
HELP: { HELP: {
{ $syntax "{ elements... }" } { $syntax "{ elements... }" }
@ -356,6 +361,12 @@ HELP: H{
{ $description "Marks the beginning of a literal hashtable, given as a list of two-element arrays holding key/value pairs. Literal hashtables are terminated by " { $link POSTPONE: } } "." } { $description "Marks the beginning of a literal hashtable, given as a list of two-element arrays holding key/value pairs. Literal hashtables are terminated by " { $link POSTPONE: } } "." }
{ $examples { $code "H{ { \"tuna\" \"fish\" } { \"jalapeno\" \"vegetable\" } }" } } ; { $examples { $code "H{ { \"tuna\" \"fish\" } { \"jalapeno\" \"vegetable\" } }" } } ;
HELP: HS{
{ $syntax "HS{ members ... }" }
{ $values { "members" "a list of objects" } }
{ $description "Marks the beginning of a literal hash set, given as a list of its members. Literal hashtables are terminated by " { $link POSTPONE: } } "." }
{ $examples { $code "HS{ 3 \"foo\" }" } } ;
HELP: C{ HELP: C{
{ $syntax "C{ real-part imaginary-part }" } { $syntax "C{ real-part imaginary-part }" }
{ $values { "real-part" "a real number" } { "imaginary-part" "a real number" } } { $values { "real-part" "a real number" } { "imaginary-part" "a real number" } }

View File

@ -8,7 +8,7 @@ generic.standard generic.hook generic.math generic.parser classes
io.pathnames vocabs vocabs.parser classes.parser classes.union io.pathnames vocabs vocabs.parser classes.parser classes.union
classes.intersection classes.mixin classes.predicate classes.intersection classes.mixin classes.predicate
classes.singleton classes.tuple.parser compiler.units classes.singleton classes.tuple.parser compiler.units
combinators effects.parser slots ; combinators effects.parser slots hash-sets ;
IN: bootstrap.syntax IN: bootstrap.syntax
! These words are defined as a top-level form, instead of with ! These words are defined as a top-level form, instead of with
@ -104,6 +104,7 @@ IN: bootstrap.syntax
"H{" [ \ } [ >hashtable ] parse-literal ] define-core-syntax "H{" [ \ } [ >hashtable ] parse-literal ] define-core-syntax
"T{" [ parse-tuple-literal suffix! ] define-core-syntax "T{" [ parse-tuple-literal suffix! ] define-core-syntax
"W{" [ \ } [ first <wrapper> ] parse-literal ] define-core-syntax "W{" [ \ } [ first <wrapper> ] parse-literal ] define-core-syntax
"HS{" [ \ } [ <hash-set> ] parse-literal ] define-core-syntax
"POSTPONE:" [ scan-word suffix! ] define-core-syntax "POSTPONE:" [ scan-word suffix! ] define-core-syntax
"\\" [ scan-word <wrapper> suffix! ] define-core-syntax "\\" [ scan-word <wrapper> suffix! ] define-core-syntax

View File

@ -11,7 +11,7 @@ IN: contributors
] with-directory ; ] with-directory ;
: patch-counts ( authors -- assoc ) : patch-counts ( authors -- assoc )
dup prune dup members
[ dup rot [ = ] with count ] with [ dup rot [ = ] with count ] with
{ } map>assoc ; { } map>assoc ;

View File

@ -29,7 +29,7 @@ IN: fuel.xref
[ word? ] filter [ word>xref ] map ; [ word? ] filter [ word>xref ] map ;
: filter-prefix ( seq prefix -- seq ) : filter-prefix ( seq prefix -- seq )
[ drop-prefix nip length 0 = ] curry filter prune ; [ drop-prefix nip length 0 = ] curry filter members ;
MEMO: (vocab-words) ( name -- seq ) MEMO: (vocab-words) ( name -- seq )
>vocab-link words [ name>> ] map ; >vocab-link words [ name>> ] map ;
@ -40,7 +40,7 @@ MEMO: (vocab-words) ( name -- seq )
append H{ } [ assoc-union ] reduce keys ; append H{ } [ assoc-union ] reduce keys ;
: vocabs-words ( names -- seq ) : vocabs-words ( names -- seq )
prune [ (vocab-words) ] map concat ; members [ (vocab-words) ] map concat ;
PRIVATE> PRIVATE>

View File

@ -145,7 +145,7 @@ TUPLE: link attributes clickable ;
[ >url ] map ; [ >url ] map ;
: find-all-links ( vector -- vector' ) : find-all-links ( vector -- vector' )
[ find-hrefs ] [ find-frame-links ] bi append prune ; [ find-hrefs ] [ find-frame-links ] bi union ;
: find-forms ( vector -- vector' ) : find-forms ( vector -- vector' )
"form" over find-opening-tags-by-name "form" over find-opening-tags-by-name

Some files were not shown because too many files have changed in this diff Show More