| Lingua-FeatureMatrix documentation | Contained in the Lingua-FeatureMatrix distribution. |
Lingua::FeatureMatrix::Implicature - Owns a single implicature within a Lingua::FeatureMatrix.
Handles a single implicature from a set of known features to provide new information for other features.
takes another Lingua::FeatureMatrix::Implicature as an
argument. Returns whether the implicant (output) of the other
implicature could affect the implier (input) of this one.
Used for rule-ordering.
Takes a Lingua::FeatureMatrix::Eme as an argument. Returns whether
this implicature would apply to this eme (whether it matches the implier).
Takes a Lingua::FeatureMatrix::Eme as an argument. Sets its
features according to the implicature's implicant.
Original version; created by h2xs 1.21 with options
-CAX Lingua::FeatureMatrix::Implicature
Jeremy Kahn, <kahn@cpan.org>
| Lingua-FeatureMatrix documentation | Contained in the Lingua-FeatureMatrix distribution. |
package Lingua::FeatureMatrix::Implicature; use 5.006; use strict; use warnings; use Carp; our $VERSION = '0.01'; use Class::MethodMaker new_with_init => 'new', # use get_set so we can initialize to undef without warning get_set => [ qw [ implier implicant ] ]; # hash => [ qw [ implier implicant ] ]; use Lingua::FeatureMatrix::Eme; ################################################################## sub init { my $self = shift; my %implier = %{shift @_}; my %implicant = %{shift @_}; { # these two calls *should* allow undef to be a value... $self->implier(\%implier); $self->implicant(\%implicant); } # foreach my $key ($self->implier_keys) { # if (not defined $self->implier($key)) { # warn "shouldn't specify * for features in implier\n" } ################################################################## sub matches { my $self = shift; my Lingua::FeatureMatrix::Eme $eme = shift; # returns whether the eme passed in by argument matches the implier FEATURE: foreach my $feature ( keys %{$self->implier()} ) { if (not $eme->can($feature)) { warn ref($eme) . " doesn't know about feature $feature\n"; next FEATURE; } if (not defined $self->implier()->{$feature}) { if (not defined $eme->$feature) { next FEATURE; # we're okay -- both underspecified } else { return 0; # implier requires "unspecified", eme has specified # it } } if (defined $self->implier()->{$feature} and not defined $eme->$feature) { return 0; # implier requires, eme has explicitly unspecified } if ($eme->$feature eq 'unset') { return 0; # doesn't match if not yet set. Is this the right # behavior? } if ($self->implier()->{$feature} != $eme->$feature) { # both defined, but different signs return 0; } } return 1; } ################################################################## sub dependsOn { # check to see if $other's implicant shares any features with # $self's implier. e.g. # other [ +high ] => [ +vow ] # self [ +vow ] => [ +voice ] # since [vow] is in other's implicant, and in self's implier, self # *does* depend on other my $self = shift; my Lingua::FeatureMatrix::Implicature $other = shift; my @dependencies; foreach my $feature( keys %{$self->implier} ) { if (defined $other->implicant->{$feature}) { my $action; if ($other->implicant->{$feature} == $self->implier->{$feature}) { $action = 'feeds'; } else { $action = 'bleeds'; } # should this test "exists"? push @dependencies, "$action ($feature)"; } } return @dependencies; } ################################################################## sub dumpToText { my $self = shift; my (@implier, @implicant); foreach (sort keys %{$self->implier()}) { push @implier, Lingua::FeatureMatrix::Eme->_dumpFeature($_, $self->implier->{$_}); } foreach (sort keys %{$self->implicant()}) { push @implicant, Lingua::FeatureMatrix::Eme->_dumpFeature($_, $self->implicant->{$_}); } return join (' ', '[', @implier, ']', '=>', '[', @implicant, ']'); } ################################################################## sub apply { my $self = shift; my Lingua::FeatureMatrix::Eme $eme = shift; # modifies the eme passed in according to the implicant foreach my $feature( keys %{$self->implicant} ) { # issues warnings if implicated field already populated? my $val = $self->implicant->{$feature}; my $isProblem; if (defined $eme->$feature() and $eme->$feature eq 'unset') { } elsif (not defined $eme->$feature()) { if (defined $val) { $isProblem = 1; } else { $isProblem = 0; } } else { # defined $eme->$feature() if (not defined $val) { $isProblem = 1; } else { # both defined $isProblem = ($eme->$feature != $val); } } if ($isProblem) { croak "implicature ", $self->dumpToText, " wanted to assign new value '", (defined $val ? $val : 'undef'), "' to $feature but eme '", $eme->name(), "' already had value '", (defined $eme->$feature ? $eme->$feature : 'undef'), "' at $feature!\n"; } elsif (defined $isProblem) { # my $implier = $eme->by_implication($feature); if (not $eme->by_implication_count($feature)) { warn (join '', "Implicature '", $self->dumpToText, "' and eme '", $eme->name(), "' definition are ", "mutually redundant with respect to the '$feature' feature\n"); } } $eme->$feature($val); $eme->by_implication_push($feature => $self); } } ################################################################## sub sortByRuleOrder { my $class = shift; my @implicatures = @_; foreach my $implicature (@implicatures) { # look for match from current implicant to another rule's implier. foreach my $otherImplicature (@implicatures) { # skip self! next if ($implicature == $otherImplicature); # if current implicant matches other implicature's implier, # current implicature must come first. # JGK: we should draw a directed arc between current and other; # then do a topological sort. } } my @sorted; # ... return @sorted; } 1; __END__