| XML-DTD documentation | Contained in the XML-DTD distribution. |
XML::DTD::FAState - Perl module representing a state of a finite automaton
use XML::DTD::FAState;
XML::DTD::FAState is a Perl module representing a state of a finite automaton. The following methods are provided.
my $s = XML::DTD::FAState->new('state label');
my $sf = XML::DTD::FAState->new('state label', 1); # Final state
Construct a new XML::DTD::FAState object.
if (XML::DTD::FAState->isa($obj) { ... }
Test object type.
print $s->label;
Return state label.
my $br = $s->backref;
Get list of back references.
my $tlst = $s->transitions;
Get all outbound transitions as list of (destination,symbol) pairs.
my $symball = $s->outsymbols;
my $s1 = XML::DTD::FAState->new('state label');
my $symbdst = $s->outsymbols(s1);
Get array of all outbound transition symbols, or just those associated with a specified destination state.
my $dstall = $s->deststates;
my $dstsmb = $s->deststates('transition symbol');
Get array of all destination states, or just those associated with a specified transition symbol.
my $dst = XML::DTD::FAState->new('state label');
my $s->settrans($dst, 'transition symbol');
Add a transition to another state.
$s->clrtrans($dst, 'transition symbol');
Remove a transition to another node.
Brendt Wohlberg <wohl@cpan.org>
Copyright (C) 2006,2010 by Brendt Wohlberg
This library is available under the terms of the GNU General Public License (GPL), described in the GPL file included in this distribution.
| XML-DTD documentation | Contained in the XML-DTD distribution. |
package XML::DTD::FAState; use 5.008; use strict; use warnings; our @ISA = qw(); our $VERSION = '0.09'; # Constructor sub new { my $proto = shift; # Class name or object reference my $label = shift; # State label my $final = shift; # Final state flag my $cls = ref($proto) || $proto; my $obj = ref($proto) && $proto; my $self; if ($obj) { # Called as a copy constructor $self = { %$obj }; } else { # Called as the main constructor $self = { 'label' => $label, # State label 'final' => $final, # Final state flag 'tdest' => {}, # Transition destinations 'tsymb' => {}, # Transition symbols 'bckrf' => {} # Back references }; } bless $self, $cls; return $self; } # Determine whether object is of this type sub isa { my $cls = shift; my $r = shift; if (defined($r) && ref($r) eq $cls) { return 1; } else { return 0; } } # Get state label sub label { my $self = shift; return $self->{'label'}; } # Get list of back references for state sub backref { my $self = shift; return [keys %{$self->{'bckrf'}}]; } # Get all outbound transitions as list of (destination,symbol) pairs sub transitions { my $self = shift; # Initialise transition list my $trns = []; # Get list of all destination states my $dest = $self->deststates; my ($d, $s, $symb); # Work through list of destination states foreach $d (@$dest) { # Get list of transition symbols for transitions to current destination $symb = $self->outsymbols($d); # Work through list of transition symbols foreach $s (@$symb) { # Push (destination state,transition symbol) pair onto list push @$trns, [$d, $s]; } } return $trns; } # Get array of all outbound transition symbols, or just those # associated with a specified destination state sub outsymbols { my $self = shift; my $dest = shift; # Destination state if (defined $dest) { return [keys %{$self->{'tdest'}->{$dest}}]; } else { return [keys %{$self->{'tsymb'}}]; } } # Get array of all destination states, or just those associated with a # specified transition symbol sub deststates { my $self = shift; my $symb = shift; # Transition symbol if (defined $symb) { return $self->{'tsymb'}->{$symb}; } else { # Get list of all outbound transition symbols my $symb = $self->outsymbols; # Initialise hash used to ensure list only contains one occurrence # of each state my $uniq = {}; # Initialise result list my $dest = []; my ($s, $d, $dlst); # Loop over all outbound transition symbols foreach $s (@$symb) { # Get list of destination states associated with current symbol $dlst = $self->deststates($s); # Loop over all destination states associated with current symbol foreach $d (@$dlst) { # Push the current state onto the list if not already encountered push @$dest, $d if (!$uniq->{$d}); # Mark the current state as having been encountered $uniq->{$d} = 1; } } return $dest; } } # Add a transition to another state sub settrans { my $self = shift; my $dest = shift; # Destination state my $symb = shift; # Transition symbol # Construct symbol hash for destination if not defined $self->{'tdest'}->{$dest} = {} if (!defined $self->{'tdest'}->{$dest}); # Construct destination array for symbol if not defined $self->{'tsymb'}->{$symb} = [] if (!defined $self->{'tsymb'}->{$symb}); # Push destination node onto list for corresponding symbol if same # (destination, symbol) transition not already present push @{$self->{'tsymb'}->{$symb}}, $dest if (!$self->{'tdest'}->{$dest}->{$symb}); # Mark symbol in hash for corresponding destination $self->{'tdest'}->{$dest}->{$symb} = 1; # Mark backreference to transition source state $dest->{'bckrf'}->{$self} = 1; } # Remove a transition to another node sub clrtrans { my $self = shift; my $dest = shift; # Destination state my $symb = shift; # Transition symbol # Remove symbol from hash for corresponding destination delete $self->{'tdest'}->{$dest}->{$symb}; # Remove destination node from list for corresponding signal my ($n, $d); my $dlst = []; foreach $d (@{$self->{'tsymb'}->{$symb}}) { push @$dlst, $d if ($d != $dest); } $self->{'tsymb'}->{$symb} = $dlst; # Delete symbol hash for destination if empty delete $self->{'tdest'}->{$dest} if (scalar @$dlst == 0); # Delete destination array for symbol if empty delete $self->{'tsymb'}->{$symb} if (scalar @{$self->deststates($symb)} == 0); # Remove backreference to transition source state delete $dest->{'bckrf'}->{$self}; } 1; __END__