GOBO
view release on metacpan or search on metacpan
GOBO/Graph.pm view on Meta::CPAN
id: y
is_a: z
Here there are only two nodes declared (x and y) but there are a total
of three references.
The noderef method can be used to access the full list of nodes that
are either declared or referenced. This is useful to avoid
instantiating multiple copies of the same object.
Methods such as terms, relations and instances return only those nodes
declared to be in the graph
=head1 SEE ALSO
GOBO::Node
GOBO::LinkStatement
=cut
package GOBO::Graph;
use Moose;
with 'GOBO::Attributed';
use strict;
use GOBO::Annotation;
use GOBO::ClassExpression::Union;
use GOBO::ClassExpression;
use GOBO::Formula;
use GOBO::Indexes::NodeIndex;
use GOBO::Indexes::StatementIndex;
use GOBO::InstanceNode;
use GOBO::LinkStatement;
use GOBO::LiteralStatement;
#use GOBO::Node;
use GOBO::RelationNode;
use GOBO::Statement;
use GOBO::Subset;
use GOBO::Synonym;
use GOBO::TermNode;
use overload ('""' => 'as_string');
has 'relation_h' => (is => 'rw', isa => 'HashRef[GOBO::TermNode]', default=>sub{{}});
has 'term_h' => (is => 'rw', isa => 'HashRef[GOBO::TermNode]', default=>sub{{}});
has 'instance_h' => (is => 'rw', isa => 'HashRef[GOBO::InstanceNode]', default=>sub{{}});
has 'link_ix' => (is => 'rw', isa => 'GOBO::Indexes::StatementIndex',
default=>sub{ new GOBO::Indexes::StatementIndex() },
handles => { links => 'statements', add_link => 'add_statement', add_links => 'add_statements', remove_links => 'remove_statements', remove_link => 'remove_statement' },
);
has 'annotation_ix' => (is => 'rw', isa => 'GOBO::Indexes::StatementIndex',
default=>sub{ new GOBO::Indexes::StatementIndex() },
handles => { annotations => 'statements', add_annotation => 'add_statement', add_annotations => 'add_statements', annotated_entities => 'referenced_nodes', remove_annotations => 'remove_statements', remove_annotation => 'remove_state...
);
#has 'node_index' => (is => 'rw', isa => 'HashRef[GOBO::Node]', default=>sub{{}});
has 'node_index' => (is => 'rw', isa => 'GOBO::Indexes::NodeIndex',
default=>sub{ new GOBO::Indexes::NodeIndex() },
handles => [ 'nodes' ],
);
has 'subset_index' => (is => 'rw', isa => 'HashRef[GOBO::Subset]', default=>sub{{}});
has 'formulae' => (is => 'rw', isa => 'ArrayRef[GOBO::Formula]', default=>sub{[]});
#sub nodes {
# my $self = shift;
# return $self->node_index->nodes;
#}
sub referenced_nodes {
my $self = shift;
return $self->node_index->nodes;
}
#sub links { shift->link_ix->statements(@_) }
#sub add_link { shift->link_ix->add_statement(@_) }
#sub add_links { shift->link_ix->add_statements(@_) }
#sub remove_link { shift->link_ix->remove_statements([@_]) }
#sub annotations { shift->annotation_ix->statements(@_) }
#sub add_annotation { shift->annotation_ix->add_statement(@_) }
#sub add_annotations { shift->annotation_ix->add_statements(@_) }
#sub remove_annotation { shift->annotation_ix->remove_statements([@_]) }
#sub annotated_entities { shift->annotation_ix->referenced_nodes }
sub has_terms {
my $self = shift;
return 1 if scalar @{$self->terms};
return undef;
}
sub has_relations {
my $self = shift;
return 1 if scalar @{$self->relations};
return undef;
}
sub has_instances {
my $self = shift;
return 1 if scalar @{$self->instances};
return undef;
}
sub has_subsets {
my $self = shift;
return 1 if scalar @{$self->declared_subsets};
return undef;
}
*has_declared_subsets = \&has_subsets;
sub has_formulae {
my $self = shift;
return 1 if scalar @{$self->formulae};
return undef;
}
sub has_links {
my $self = shift;
return 1 if scalar @{$self->links};
return undef;
}
sub has_annotations {
my $self = shift;
return 1 if scalar @{$self->annotations};
return undef;
}
sub has_nodes {
my $self = shift;
return 1 if scalar @{$self->nodes};
return undef;
}
=head2 declared_subsets
- returns ArrayRef[GOBO::Subset]
returns the subsets declared in this graph.
See also: GOBO::TermNode->subsets() - this returns the subsets a term belongs to
=cut
# @Override
sub declared_subsets {
my $self = shift;
if (@_) {
my $ssl = shift;
$self->subset_index->{$_->id} = $_ foreach @$ssl;
}
return [values %{$self->subset_index()}];
}
=head2 terms
- Returns: ArrayRef[GOBO::TermNode], where each member is a term belonging to this graph
=cut
sub terms {
my $self = shift;
#$self->node_index->nodes_by_metaclass('term');
return [values %{$self->term_h}];
}
=head2 get_term
- Argument: id Str
- Returns: GOBO::TermNode, if term is declared in this graph
GOBO/Graph.pm view on Meta::CPAN
sub add_relation {
my $self = shift;
my $n = $self->relation_noderef(@_);
$self->relation_h->{$n->id} = $n;
return $n;
}
=head2 add_instance
- Arguments: Str or GOBO::Node
- Returns: GOBO::InstanceNode
adds the object to the list of instances referenced in this
graph. Forces the class to be GOBO::InstanceNode
=cut
sub add_instance {
my $self = shift;
my $n = $self->instance_noderef(@_);
$self->instance_h->{$n->id} = $n;
return $n;
}
=head2 remove_node
- Arguments: node GOBO::Node, cascade Bool[OPT]
unlinks the node from this graph
If cascade is 0 or undef, any links to or from this node will remain as dangling links.
If cascade is set, then links to and from this node will also be deleted
=cut
sub remove_node {
my $self = shift;
my $n = shift;
my $cascade = shift;
#my $id = ref($n) ? $n->id : $n;
my $id = $n->id;
if ($self->term_h->{$id}) {
delete $self->term_h->{$id};
}
if ($self->instance_h->{$id}) {
delete $self->instance_h->{$id};
}
if ($self->relation_h->{$id}) {
delete $self->relation_h->{$id};
}
if ($cascade) {
$self->remove_link($_) foreach @{$self->get_outgoing_links($n)};
$self->remove_link($_) foreach @{$self->get_incoming_links($n)};
}
return $self->node_index->remove_node($n);
}
sub add_formula { my $self = shift; push(@{$self->formulae},@_) }
=head2 get_outgoing_links (subject GOBO::Node, relation GOBO::RelationNode OPTIONAL)
given a subject (child), get target (parent) links
if relation is specified, also filters results on relation
=cut
sub get_outgoing_links {
my $self = shift;
my $n = shift;
my $rel = shift;
my @sl = @{$self->link_ix->statements_by_node_id(ref($n) ? $n->id : $n) || []};
# if x = a AND r(b), then x r b
if (ref($n) && $n->isa('GOBO::ClassExpression::Intersection')) {
foreach (@{$n->arguments}) {
if ($_->isa('GOBO::ClassExpression::RelationalExpression')) {
push(@sl, new GOBO::LinkStatement(node=>$n,relation=>$_->relation,target=>$_->target));
}
else {
push(@sl, new GOBO::LinkStatement(node=>$n,relation=>'is_a',target=>$_));
}
}
}
if ($rel) {
# TODO: use indexes to make this faster
my $rid = ref($rel) ? $rel->id : $rel;
@sl = grep {$_->relation->id eq $rid} @sl;
}
return \@sl;
}
# @Deprecated
*get_target_links = \&get_outgoing_links;
=head2 get_incoming_links (subject GOBO::Node, relation GOBO::RelationNode OPTIONAL)
given a subject (child), get target (parent) links
if relation is specified, also filters results on relation
=cut
sub get_incoming_links {
my $self = shift;
my $n = shift;
my $rel = shift;
my @sl = @{$self->link_ix->statements_by_target_id(ref($n) ? $n->id : $n) || []};
if ($rel) {
# TODO: use indexes to make this faster
my $rid = ref($rel) ? $rel->id : $rel;
@sl = grep {$_->relation->id eq $rid} @sl;
}
return \@sl;
}
=head2 get_is_a_roots
- Argument: none
( run in 0.696 second using v1.01-cache-2.11-cpan-99c4e6809bf )