2006-08-02 02:49:23 -04:00
|
|
|
! Copyright (C) 2004, 2006 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
IN: generic
|
2006-08-02 15:17:13 -04:00
|
|
|
USING: arrays definitions errors hashtables kernel
|
2006-08-15 16:29:35 -04:00
|
|
|
kernel-internals namespaces sequences strings words
|
2006-08-15 04:57:12 -04:00
|
|
|
vectors math parser ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
PREDICATE: word class ( obj -- ? ) "class" word-prop ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
|
|
|
SYMBOL: typemap
|
2006-08-17 23:50:59 -04:00
|
|
|
SYMBOL: class<map
|
2006-08-02 02:49:23 -04:00
|
|
|
SYMBOL: builtins
|
|
|
|
|
2006-08-17 23:50:59 -04:00
|
|
|
: classes ( -- seq ) class<map get hash-keys ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: type>class ( n -- class ) builtins get nth ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: predicate-word ( word -- predicate )
|
2006-08-02 02:49:23 -04:00
|
|
|
word-name "?" append create-in ;
|
|
|
|
|
2006-08-15 04:57:12 -04:00
|
|
|
: predicate-effect 1 1 <effect> ;
|
|
|
|
|
2006-08-02 02:49:23 -04:00
|
|
|
: define-predicate ( class predicate quot -- )
|
|
|
|
over [
|
2006-08-15 04:57:12 -04:00
|
|
|
over predicate-effect "declared-effect" set-word-prop
|
2006-08-02 02:49:23 -04:00
|
|
|
dupd define-compound
|
|
|
|
2dup unit "predicate" set-word-prop
|
|
|
|
swap "predicating" set-word-prop
|
|
|
|
] [
|
|
|
|
3drop
|
|
|
|
] if ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: superclass ( class -- super ) "superclass" word-prop ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-17 23:50:59 -04:00
|
|
|
: members ( class -- seq ) "members" word-prop ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
|
|
|
: (flatten-class) ( class -- )
|
|
|
|
dup members [ [ (flatten-class) ] each ] [ dup set ] ?if ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: flatten-class ( class -- seq )
|
2006-08-02 02:49:23 -04:00
|
|
|
[ (flatten-class) ] make-hash ;
|
|
|
|
|
|
|
|
: (types) ( class -- )
|
|
|
|
flatten-class [
|
|
|
|
drop dup superclass
|
|
|
|
[ (types) ] [ "type" word-prop dup set ] ?if
|
|
|
|
] hash-each ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: types ( class -- seq )
|
2006-08-02 02:49:23 -04:00
|
|
|
[ (types) ] make-hash hash-keys natural-sort ;
|
|
|
|
|
|
|
|
DEFER: (class<)
|
|
|
|
|
|
|
|
: superclass< ( cls1 cls2 -- ? )
|
|
|
|
>r superclass r> 2dup and [ (class<) ] [ 2drop f ] if ;
|
|
|
|
|
|
|
|
: union-class< ( cls1 cls2 -- ? )
|
|
|
|
[ flatten-class ] 2apply hash-keys swap
|
|
|
|
[ drop swap [ (class<) ] contains-with? ] hash-all-with? ;
|
|
|
|
|
|
|
|
: class-empty? ( class -- ? )
|
|
|
|
members dup [ empty? ] when ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: (class<) ( class1 class2 -- ? )
|
2006-08-02 02:49:23 -04:00
|
|
|
{
|
|
|
|
{ [ 2dup eq? ] [ 2drop t ] }
|
|
|
|
{ [ over class-empty? ] [ 2drop t ] }
|
|
|
|
{ [ 2dup superclass< ] [ 2drop t ] }
|
|
|
|
{ [ 2dup [ members ] 2apply or not ] [ 2drop f ] }
|
|
|
|
{ [ t ] [ union-class< ] }
|
|
|
|
} cond ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: class< ( class1 class2 -- ? )
|
2006-08-17 23:50:59 -04:00
|
|
|
class<map get hash hash-member? ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: class-compare ( class1 class2 -- n )
|
2006-08-02 02:49:23 -04:00
|
|
|
2dup eq? [ 2drop 0 ] [ class< 1 -1 ? ] if ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: lookup-union ( classes -- class )
|
2006-08-02 02:49:23 -04:00
|
|
|
typemap get hash [ object ] unless* ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: types* ( class -- classes )
|
|
|
|
types [ type>class dup ] map>hash ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-06 22:30:52 -04:00
|
|
|
: (class-or) ( class class -- class )
|
2006-08-07 01:17:04 -04:00
|
|
|
[ types* ] 2apply hash-union lookup-union ;
|
2006-08-06 22:30:52 -04:00
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: class-or ( class1 class2 -- class )
|
2006-08-06 22:30:52 -04:00
|
|
|
{
|
|
|
|
{ [ 2dup class< ] [ nip ] }
|
|
|
|
{ [ 2dup swap class< ] [ drop ] }
|
|
|
|
{ [ t ] [ (class-or) ] }
|
|
|
|
} cond ;
|
|
|
|
|
2006-08-02 02:49:23 -04:00
|
|
|
: (class-and) ( class class -- class )
|
2006-08-07 01:17:04 -04:00
|
|
|
[ types* ] 2apply hash-intersect lookup-union ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: class-and ( class1 class2 -- class )
|
2006-08-02 02:49:23 -04:00
|
|
|
{
|
|
|
|
{ [ 2dup class< ] [ drop ] }
|
|
|
|
{ [ 2dup swap class< ] [ nip ] }
|
|
|
|
{ [ t ] [ (class-and) ] }
|
|
|
|
} cond ;
|
|
|
|
|
2006-08-16 21:55:53 -04:00
|
|
|
: classes-intersect? ( class1 class2 -- ? )
|
2006-08-02 02:49:23 -04:00
|
|
|
class-and class-empty? not ;
|
|
|
|
|
|
|
|
: min-class ( class seq -- class/f )
|
|
|
|
[ dupd classes-intersect? ] subset dup empty? [
|
|
|
|
2drop f
|
|
|
|
] [
|
|
|
|
tuck [ class< ] all-with? [ peek ] [ drop f ] if
|
|
|
|
] if ;
|
|
|
|
|
2006-08-17 23:50:59 -04:00
|
|
|
: smaller-classes ( class -- seq )
|
|
|
|
classes [ swap (class<) ] subset-with ;
|
|
|
|
|
|
|
|
: smaller-classes+ ( class -- )
|
|
|
|
[ smaller-classes [ dup ] map>hash ] keep
|
|
|
|
class<map get set-hash ;
|
|
|
|
|
|
|
|
: bigger-classes ( class -- seq )
|
|
|
|
classes [ (class<) ] subset-with ;
|
|
|
|
|
|
|
|
: bigger-classes+ ( class -- )
|
|
|
|
dup bigger-classes
|
|
|
|
[ dupd class<map get hash set-hash ] each-with ;
|
|
|
|
|
2006-08-02 02:49:23 -04:00
|
|
|
: define-class ( class -- )
|
|
|
|
dup t "class" set-word-prop
|
2006-08-17 23:50:59 -04:00
|
|
|
dup dup flatten-class typemap get set-hash
|
|
|
|
dup smaller-classes+ bigger-classes+ ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
|
|
|
! Predicate classes for generalized predicate dispatch.
|
|
|
|
: define-predicate-class ( class predicate definition -- )
|
|
|
|
pick define-class
|
|
|
|
3dup nip "definition" set-word-prop
|
|
|
|
pick superclass "predicate" word-prop
|
|
|
|
[ \ dup , % , [ drop f ] , \ if , ] [ ] make
|
|
|
|
define-predicate ;
|
|
|
|
|
2006-08-02 16:53:26 -04:00
|
|
|
PREDICATE: class predicate "definition" word-prop ;
|
2006-08-02 02:49:23 -04:00
|
|
|
|
|
|
|
! Union classes for dispatch on multiple classes.
|
2006-08-16 21:55:53 -04:00
|
|
|
: union-predicate ( seq -- quot )
|
2006-08-02 02:49:23 -04:00
|
|
|
[ dup ] swap [ "predicate" word-prop append ] map-with
|
|
|
|
[ [ drop t ] 2array ] map [ drop f ] swap alist>quot ;
|
|
|
|
|
|
|
|
: set-members ( class members -- )
|
|
|
|
[ bootstrap-word ] map "members" set-word-prop ;
|
|
|
|
|
|
|
|
: define-union ( class predicate members -- )
|
|
|
|
3dup nip set-members pick define-class
|
|
|
|
union-predicate define-predicate ;
|
|
|
|
|
2006-08-02 16:53:26 -04:00
|
|
|
PREDICATE: class union members ;
|
2006-08-02 15:17:13 -04:00
|
|
|
|
|
|
|
! Definition protocol
|
2006-08-17 23:50:59 -04:00
|
|
|
: smaller-classes- ( class -- )
|
|
|
|
class<map get remove-hash ;
|
|
|
|
|
|
|
|
: bigger-classes- ( class -- )
|
|
|
|
classes [ class<map get hash remove-hash ] each-with ;
|
|
|
|
|
2006-08-02 16:53:26 -04:00
|
|
|
: forget-class ( class -- )
|
|
|
|
dup "predicate" word-prop [ forget ] each
|
2006-08-17 23:50:59 -04:00
|
|
|
dup dup flatten-class typemap get remove-hash forget-word
|
|
|
|
dup smaller-classes- bigger-classes- ;
|
2006-08-02 16:53:26 -04:00
|
|
|
|
|
|
|
M: class forget forget-class ;
|