2008-02-18 20:12:10 -05:00
|
|
|
! Copyright (C) 2008 Alex Chapman
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-03-20 11:01:58 -04:00
|
|
|
USING: accessors arrays combinators.cleave continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots parser sequences sequences.deep sequences.lib words ;
|
2008-02-18 20:12:10 -05:00
|
|
|
IN: semantic-db
|
|
|
|
|
|
|
|
TUPLE: node id content ;
|
|
|
|
: <node> ( content -- node )
|
|
|
|
node construct-empty swap >>content ;
|
|
|
|
|
2008-03-06 07:54:16 -05:00
|
|
|
: <id-node> ( id -- node )
|
|
|
|
node construct-empty swap >>id ;
|
|
|
|
|
2008-02-18 20:12:10 -05:00
|
|
|
node "node"
|
|
|
|
{
|
2008-02-28 21:51:59 -05:00
|
|
|
{ "id" "id" +native-id+ +autoincrement+ }
|
2008-02-18 20:12:10 -05:00
|
|
|
{ "content" "content" TEXT }
|
|
|
|
} define-persistent
|
|
|
|
|
2008-03-06 07:54:16 -05:00
|
|
|
: delete-node ( node-id -- )
|
|
|
|
<id-node> delete-tuple ;
|
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
: create-node ( str -- node-id )
|
2008-02-28 21:51:59 -05:00
|
|
|
<node> dup insert-tuple id>> ;
|
2008-02-18 20:12:10 -05:00
|
|
|
|
2008-03-06 07:54:16 -05:00
|
|
|
: node-content ( id -- str )
|
|
|
|
f <node> swap >>id select-tuple content>> ;
|
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
TUPLE: arc id subject object relation ;
|
2008-02-18 20:12:10 -05:00
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
: <arc> ( subject object relation -- arc )
|
|
|
|
arc construct-empty swap >>relation swap >>object swap >>subject ;
|
2008-02-18 20:12:10 -05:00
|
|
|
|
2008-03-06 07:54:16 -05:00
|
|
|
: <id-arc> ( id -- arc )
|
|
|
|
arc construct-empty swap >>id ;
|
|
|
|
|
|
|
|
: insert-arc ( arc -- )
|
|
|
|
f <node> dup insert-tuple id>> >>id insert-tuple ;
|
|
|
|
|
|
|
|
: delete-arc ( arc-id -- )
|
|
|
|
dup delete-node <id-arc> delete-tuple ;
|
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
: create-arc ( subject object relation -- arc-id )
|
2008-03-06 07:54:16 -05:00
|
|
|
<arc> dup insert-arc id>> ;
|
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
: has-arc? ( subject object relation -- ? )
|
|
|
|
<arc> select-tuples length 0 > ;
|
|
|
|
|
|
|
|
: select-arcs ( subject object relation -- arcs )
|
|
|
|
<arc> select-tuples ;
|
|
|
|
|
|
|
|
: select-arc-ids ( subject object relation -- arc-ids )
|
|
|
|
select-arcs [ id>> ] map ;
|
|
|
|
|
|
|
|
: select-arc-subjects ( subject object relation -- subject-ids )
|
|
|
|
select-arcs [ subject>> ] map ;
|
|
|
|
|
|
|
|
: select-arc-objects ( subject object relation -- object-ids )
|
|
|
|
select-arcs [ object>> ] map ;
|
|
|
|
|
|
|
|
: delete-arcs ( subject object relation -- )
|
|
|
|
select-arcs [ id>> delete-arc ] each ;
|
|
|
|
|
|
|
|
: subject-relation ( subject relation -- subject object relation )
|
|
|
|
f swap ;
|
|
|
|
|
|
|
|
: object-relation ( object relation -- subject object relation )
|
|
|
|
f -rot ;
|
|
|
|
|
2008-02-18 20:12:10 -05:00
|
|
|
arc "arc"
|
|
|
|
{
|
2008-03-05 20:37:51 -05:00
|
|
|
{ "id" "id" INTEGER +assigned-id+ } ! foreign key to node table?
|
2008-02-28 21:51:59 -05:00
|
|
|
{ "relation" "relation" INTEGER +not-null+ }
|
|
|
|
{ "subject" "subject" INTEGER +not-null+ }
|
|
|
|
{ "object" "object" INTEGER +not-null+ }
|
2008-02-18 20:12:10 -05:00
|
|
|
} define-persistent
|
|
|
|
|
|
|
|
: create-bootstrap-nodes ( -- )
|
2008-03-19 06:22:15 -04:00
|
|
|
"semantic-db" create-node drop
|
2008-03-20 11:01:58 -04:00
|
|
|
"has-context" create-node drop ;
|
2008-03-05 20:37:51 -05:00
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
: semantic-db-context 1 ;
|
2008-03-06 07:54:16 -05:00
|
|
|
: has-context-relation 2 ;
|
2008-03-05 20:37:51 -05:00
|
|
|
|
2008-02-18 20:12:10 -05:00
|
|
|
: create-bootstrap-arcs ( -- )
|
2008-03-19 06:22:15 -04:00
|
|
|
has-context-relation semantic-db-context has-context-relation create-arc drop ;
|
2008-02-18 20:12:10 -05:00
|
|
|
|
|
|
|
: init-semantic-db ( -- )
|
2008-03-20 11:01:58 -04:00
|
|
|
node create-table
|
|
|
|
arc create-table
|
|
|
|
create-bootstrap-nodes create-bootstrap-arcs ;
|
2008-02-18 20:12:10 -05:00
|
|
|
|
2008-02-28 21:51:59 -05:00
|
|
|
: param ( value key type -- param )
|
2008-03-05 20:37:51 -05:00
|
|
|
swapd 3array ;
|
|
|
|
|
|
|
|
: single-int-results ( bindings sql -- array )
|
|
|
|
f f <simple-statement> [ do-bound-query ] with-disposal
|
|
|
|
[ first string>number ] map ;
|
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
: ensure1 ( x quot1 quot2 -- y )
|
|
|
|
#! quot1 ( x -- y/f ) tries to find an existing y
|
|
|
|
#! quot2 ( x -- y ) creates a new y if quot1 returns f
|
|
|
|
>r dupd call [ nip ] r> if* ;
|
|
|
|
|
2008-03-05 20:37:51 -05:00
|
|
|
: ensure2 ( x y quot1 quot2 -- z )
|
2008-03-20 11:01:58 -04:00
|
|
|
#! quot1 ( x y -- z/f ) tries to find an existing z
|
2008-03-05 20:37:51 -05:00
|
|
|
#! quot2 ( x y -- z ) creates a new z if quot1 returns f
|
|
|
|
>r >r 2dup r> call [ 2nip ] r> if* ;
|
2008-03-10 20:44:03 -04:00
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
! contexts:
|
|
|
|
! - a node n is a context iff there exists a relation r such that r has context n
|
2008-03-19 06:22:15 -04:00
|
|
|
: create-context ( context-name -- context-id ) create-node ;
|
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
: get-context ( context-name -- context-id/f )
|
|
|
|
[
|
|
|
|
":name" TEXT param ,
|
|
|
|
has-context-relation ":has_context" INTEGER param ,
|
|
|
|
] { } make
|
|
|
|
"select distinct n.id from node n, arc a where n.content = :name and a.relation = :has_context and a.object = n.id"
|
|
|
|
single-int-results ?first ;
|
|
|
|
|
|
|
|
: context-id ( context-name -- context-id )
|
|
|
|
[ get-context ] [ create-context ] ensure1 ;
|
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
! relations:
|
|
|
|
! - have a context in context 'semantic-db'
|
|
|
|
|
|
|
|
: create-relation ( relation-name context-id -- relation-id )
|
|
|
|
[ create-node dup ] dip has-context-relation create-arc drop ;
|
|
|
|
|
|
|
|
: get-relation ( relation-name context-id -- relation-id/f )
|
|
|
|
[
|
|
|
|
":context" INTEGER param ,
|
|
|
|
":name" TEXT param ,
|
|
|
|
has-context-relation ":has_context" INTEGER param ,
|
|
|
|
] { } make
|
|
|
|
"select n.id from node n, arc a where n.content = :name and n.id = a.subject and a.relation = :has_context and a.object = :context"
|
|
|
|
single-int-results ?first ;
|
|
|
|
|
|
|
|
: relation-id ( relation-name context-id -- relation-id )
|
|
|
|
[ get-relation ] [ create-relation ] ensure2 ;
|
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
! RELATION: is-fooey
|
|
|
|
! - define a word is-fooey in the current vocab (foo), that when called:
|
|
|
|
! - finds or creates a node called "is-fooey" with context "foo", and returns its id
|
|
|
|
: RELATION:
|
|
|
|
CREATE-WORD dup [ word-name ] [ word-vocabulary ] bi
|
|
|
|
[ context-id relation-id ] 2curry define ; parsing
|
|
|
|
|
2008-03-19 06:22:15 -04:00
|
|
|
! hierarchy
|
|
|
|
TUPLE: tree id children ;
|
|
|
|
C: <tree> tree
|
|
|
|
|
2008-03-20 11:01:58 -04:00
|
|
|
: parent-child ( parent child has-parent-relation -- arc-id )
|
|
|
|
swapd create-arc ;
|
2008-03-19 06:22:15 -04:00
|
|
|
|
|
|
|
: un-parent-child ( parent child has-parent-relation -- )
|
2008-03-20 11:01:58 -04:00
|
|
|
swapd delete-arcs ;
|
2008-03-19 06:22:15 -04:00
|
|
|
|
|
|
|
: children ( node-id has-parent-relation -- children )
|
2008-03-20 11:01:58 -04:00
|
|
|
object-relation select-arc-subjects ;
|
2008-03-19 06:22:15 -04:00
|
|
|
|
|
|
|
: parents ( node-id has-parent-relation -- parents )
|
2008-03-20 11:01:58 -04:00
|
|
|
subject-relation select-arc-objects ;
|
2008-03-19 06:22:15 -04:00
|
|
|
|
|
|
|
: get-node-hierarchy ( node-id has-parent-relation -- tree )
|
|
|
|
2dup children >r [ get-node-hierarchy ] curry r> swap map <tree> ;
|
|
|
|
|
|
|
|
: (get-root-nodes) ( node-id has-parent-relation -- root-nodes/node-id )
|
|
|
|
2dup parents dup empty? [
|
|
|
|
2drop
|
|
|
|
] [
|
|
|
|
>r nip [ (get-root-nodes) ] curry r> swap map
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: get-root-nodes ( node-id has-parent-relation -- root-nodes )
|
|
|
|
(get-root-nodes) flatten prune ;
|
|
|
|
|
|
|
|
! sets
|
2008-03-20 11:01:58 -04:00
|
|
|
: in-set ( member set in-set-relation -- arc-id ) create-arc ;
|
|
|
|
: in-set? ( member set in-set-relation -- ? ) has-arc? ;
|
2008-03-19 06:22:15 -04:00
|
|
|
: set-members ( set in-set-relation -- members )
|
2008-03-20 11:01:58 -04:00
|
|
|
object-relation select-arc-subjects ;
|
|
|
|
|
|
|
|
! attributes
|
|
|
|
: has-attribute ( node value has-attribute-relation -- arc-id ) create-arc ;
|
|
|
|
: has-attribute? ( node value has-attribute-relation -- ? ) has-arc? ;
|
|
|
|
: nodes-with-attribute ( value has-attribute-relation -- node-ids )
|
|
|
|
object-relation select-arc-subjects ;
|