File Coverage

blib/lib/Treex/Core/Node/InClause.pm
Criterion Covered Total %
statement 12 59 20.3
branch 0 24 0.0
condition 0 21 0.0
subroutine 4 11 36.3
pod 6 6 100.0
total 22 121 18.1


line stmt bran cond sub pod time code
1             package Treex::Core::Node::InClause;
2             $Treex::Core::Node::InClause::VERSION = '2.20210102';
3 24     24   17010 use Moose::Role;
  24         64  
  24         192  
4              
5             # with Moose >= 2.00, this must be present also in roles
6 24     24   129208 use MooseX::SemiAffordanceAccessor;
  24         63  
  24         214  
7 24     24   64302 use Treex::Core::Log;
  24         63  
  24         2007  
8 24     24   177 use List::Util qw(first); # TODO: this wouldn't be needed if there was Treex::Core::Common for roles
  24         55  
  24         19029  
9              
10             has clause_number => (
11             is => 'rw',
12             isa => 'Maybe[Int]',
13             documentation => 'ordinal number that is shared by all nodes of a clause',
14             );
15              
16             has is_clause_head => (
17             is => 'rw',
18             isa => 'Bool',
19             documentation => 'Is this node a head of a finite clause?',
20             );
21              
22             sub get_clause_root {
23 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
24 0           my $self = shift;
25 0           my $my_number = $self->clause_number;
26 0 0         log_warn( 'Attribute clause_number not defined in ' . $self->id ) if !defined $my_number;
27 0 0         return $self if !$my_number;
28              
29 0           my $highest = $self;
30 0           my $parent = $self->get_parent();
31 0   0       while ( $parent && ( $parent->clause_number || 0 ) == $my_number ) {
      0        
32 0           $highest = $parent;
33 0           $parent = $parent->get_parent();
34             }
35 0 0 0       if ( $parent && !$highest->is_member && $parent->is_coap_root() ) {
      0        
36 0 0 0 0     my $eff_parent = first { $_->is_member && ( $_->clause_number || 0 ) == $my_number } $parent->get_children();
  0            
37 0 0         return $eff_parent if $eff_parent;
38             }
39 0           return $highest;
40             }
41              
42             # Clauses may by split in more subtrees ("Peter eats and drinks.")
43             sub get_clause_nodes {
44 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
45 0           my $self = shift;
46 0           my $root = $self->get_root();
47 0           my @descendants = $root->get_descendants( { ordered => 1 } );
48 0           my $my_number = $self->clause_number;
49 0   0       return grep { ( $_->clause_number || '' ) eq $my_number } @descendants;
  0            
50             }
51              
52             # TODO: same purpose as get_clause_root but instead of clause_number uses is_clause_head
53             sub get_clause_head {
54 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
55 0           my $self = shift;
56 0           my $node = $self;
57 0   0       while ( !$node->is_clause_head && $node->get_parent() ) {
58 0           $node = $node->get_parent();
59             }
60 0           return $node;
61             }
62              
63             sub get_clause_ehead {
64 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
65 0           my $self = shift;
66 0 0         return $self if $self->is_clause_head;
67 0           my ($node) = $self->get_eparents( { or_topological => 1 } );
68 0   0       while ( !$node->is_clause_head && $node->get_parent() ) {
69 0           $node = $node->get_parent();
70             }
71 0           return $node;
72             }
73              
74             # Alternative API could be: $node->get_descendants({within_clause=>1});
75             sub get_clause_descendants {
76 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
77 0           my $self = shift;
78              
79 0           my @clause_children = grep { !$_->is_clause_head } $self->get_children();
  0            
80 0           return ( @clause_children, map { $_->get_clause_descendants() } @clause_children );
  0            
81             }
82              
83             # A variant of the previous, using effective children instead of children.
84             sub get_clause_edescendants {
85 0 0   0 1   log_fatal 'Incorrect number of arguments' if @_ != 1;
86 0           my $self = shift;
87              
88 0           my @clause_children = grep { !$_->is_clause_head } $self->get_echildren({or_topological=>1});
  0            
89              
90             # we can use normal get_clause_descendants here, using echildren would no longer make any difference
91 0           return ( @clause_children, map { $_->get_clause_descendants() } @clause_children );
  0            
92             }
93              
94             1;
95              
96             __END__
97              
98             =encoding utf-8
99              
100             =head1 NAME
101              
102             Treex::Core::Node::InClause
103              
104             =head1 VERSION
105              
106             version 2.20210102
107              
108             =head1 DESCRIPTION
109              
110             Moose role for nodes in trees where (linguistic) clauses can be recognized
111             based on attributes C<clause_number> and C<is_clause_head>.
112              
113             =head1 ATTRIBUTES
114              
115             =over
116              
117             =item clause_number
118              
119             Ordinal number that is shared by all nodes of a same clause.
120              
121             =item is_clause_head
122              
123             Is this node a head of a finite clause.
124              
125             =back
126              
127             =head1 METHODS
128              
129             =over
130              
131             =item my $clause_head_node = $node->get_clause_root();
132              
133             Returns the head node of a clause.
134             This implementation is based on the attribute C<clause_number>.
135             Note that it may give different results than C<get_clause_head>.
136              
137             =item $clause_head_node = $node->get_clause_head();
138              
139             Returns the head node of a clause.
140             This implementation is based on the attribute C<is_clause_head>.
141             Note that it may give different results than C<get_clause_root>.
142              
143             =item $clause_head_node = $node->get_clause_ehead();
144              
145             Returns the (first) effective head node of a clause.
146             Same as previous, but based on the effective parent relation.
147              
148             =item my @nodes = $node->get_clause_descendants();
149              
150             Returns those descendants which are in the same clause as C<$node>.
151             The current implementation is based on the attribute C<is_clause_head>.
152              
153             =item my @nodes = $node->get_clause_edescendants();
154              
155             Same as previous, but using the effective children relation.
156              
157             =item my @nodes = $node->get_clause_nodes();
158              
159             Returns all nodes of the clause (to which the C<$node> belongs).
160             The current implementation is based on the attribute C<clause_number>.
161              
162             =back
163              
164              
165             =head1 AUTHOR
166              
167             Martin Popel <popel@ufal.mff.cuni.cz>
168              
169             =head1 COPYRIGHT AND LICENSE
170              
171             Copyright © 2011 by Institute of Formal and Applied Linguistics, Charles University in Prague
172              
173             This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.