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