tweak options for classifying readings and relationships. Needed for tla/stemmaweb#33
[scpubgit/stemmatology.git] / base / lib / Text / Tradition / Collation / Relationship.pm
CommitLineData
22222af9 1package Text::Tradition::Collation::Relationship;
2
3use Moose;
4use Moose::Util::TypeConstraints;
5
d8ef0a2b 6enum 'RelationshipScope' => [ qw( local document global ) ];
22222af9 7
8no Moose::Util::TypeConstraints;
9
027d819c 10=head1 NAME
11
12Text::Tradition::Collation::Relationship - represents a syntactic or semantic
13relationship between two readings
14
15=head1 DESCRIPTION
16
17Text::Tradition is a library for representation and analysis of collated
18texts, particularly medieval ones. A relationship connects two readings
19within a collation, usually when they appear in the same place in different
20texts.
21
22=head1 CONSTRUCTOR
23
24=head2 new
25
26Creates a new relationship. Usually called via $collation->add_relationship.
27Options include:
28
22222af9 29=over 4
30
0fa07e25 31=item * type - Can be one of spelling, orthographic, grammatical, lexical,
32collated, repetition, transposition. All but the last two are only valid
33relationships between readings that occur at the same point in the text.
34The 'collated' relationship should only be used by parsers to align readings
35in the graph when the input information would otherwise be lost, e.g. from
36an alignment table.
22222af9 37
0fa07e25 38=item * displayform - (Optional) The reading that should be displayed if the
39related nodes are treated as one.
732e9c4e 40
0fa07e25 41=item * scope - (Optional) A meta-attribute. Can be one of 'local',
42'document', or 'global'. Denotes whether the relationship between the two
43readings holds always, independent of context, either within this tradition
44or across all traditions.
4633f9e4 45
0fa07e25 46=item * annotation - (Optional) A freeform note to attach to the relationship.
4633f9e4 47
94654e27 48=item * alters_meaning - Indicate whether, in context, the related words cause
49the text to have different meanings. Possible values are 0 (no), 1 (slightly),
50and >1 (yes).
51
0fa07e25 52=item * non_correctable - (Optional) True if the reading would not have been
53corrected independently.
22222af9 54
0fa07e25 55=item * non_independent - (Optional) True if the variant is unlikely to have
56occurred independently in unrelated witnesses.
22222af9 57
22222af9 58=back
59
027d819c 60=head1 ACCESSORS
61
62=head2 type
63
64=head2 displayform
65
66=head2 scope
67
4633f9e4 68=head2 annotation
69
027d819c 70=head2 non_correctable
71
72=head2 non_independent
73
74See the option descriptions above.
75
22222af9 76=cut
77
78has 'type' => (
79 is => 'ro',
24efa55d 80 isa => 'Str',
22222af9 81 required => 1,
82 );
83
84has 'reading_a' => (
85 is => 'ro',
86 isa => 'Str',
87 required => 1,
88 );
89
90has 'reading_b' => (
91 is => 'ro',
92 isa => 'Str',
93 required => 1,
94 );
95
732e9c4e 96has 'displayform' => (
97 is => 'ro',
98 isa => 'Str',
99 predicate => 'has_displayform',
100 );
101
22222af9 102has 'scope' => (
103 is => 'ro',
104 isa => 'RelationshipScope',
105 default => 'local',
106 );
4633f9e4 107
108has 'annotation' => (
109 is => 'ro',
110 isa => 'Str',
31aaf446 111 predicate => 'has_annotation',
4633f9e4 112 );
94654e27 113
114has 'alters_meaning' => (
115 is => 'rw',
116 isa => 'Int',
117 default => 0,
118 );
22222af9 119
4a5f5143 120has 'a_derivable_from_b' => (
22222af9 121 is => 'ro',
122 isa => 'Bool',
123 );
4a5f5143 124
125has 'b_derivable_from_a' => (
126 is => 'ro',
127 isa => 'Bool',
128 );
129
22222af9 130has 'non_independent' => (
131 is => 'ro',
132 isa => 'Bool',
133 );
732e9c4e 134
94654e27 135around 'alters_meaning' => sub {
136 my $orig = shift;
137 my $self = shift;
138 if( @_ ) {
139 if( $_[0] eq 'no' ) {
140 return $self->$orig( 0 );
141 } elsif( $_[0] eq 'slightly' ) {
142 return $self->$orig( 1 );
143 } elsif( $_[0] eq 'yes' ) {
144 return $self->$orig( 2 );
145 }
146 }
147 return $self->$orig( @_ );
148};
149
22222af9 150# A read-only meta-Boolean attribute.
027d819c 151
152=head2 colocated
153
154Returns true if the relationship type is one that requires that its readings
155occupy the same place in the collation.
156
157=cut
158
22222af9 159sub colocated {
160 my $self = shift;
161 return $self->type !~ /^(repetition|transposition)$/;
162}
163
027d819c 164=head2 nonlocal
165
166Returns true if the relationship scope is anything other than 'local'.
167
168=cut
169
22222af9 170sub nonlocal {
171 my $self = shift;
172 return $self->scope ne 'local';
173}
174
24efa55d 175=head2 is_equivalent( $otherrel )
176
177Returns true if the type and scope of $otherrel match ours.
178
179=cut
180
181sub is_equivalent {
182 my( $self, $other, $check_ann ) = @_;
183 my $oksofar = $self->type eq $other->type && $self->scope eq $other->scope;
184 if( $check_ann ) {
185 return $oksofar && $self->annotation eq $other->annotation;
186 } else {
187 return $oksofar;
188 }
189}
190
22222af9 191no Moose;
192__PACKAGE__->meta->make_immutable;
193
1941;