diff options
Diffstat (limited to 'lib/Kratos/DFADriver')
-rw-r--r-- | lib/Kratos/DFADriver/DFA.pm | 20 | ||||
-rw-r--r-- | lib/Kratos/DFADriver/Model.pm | 87 |
2 files changed, 78 insertions, 29 deletions
diff --git a/lib/Kratos/DFADriver/DFA.pm b/lib/Kratos/DFADriver/DFA.pm index 33d96c3..9b581d8 100644 --- a/lib/Kratos/DFADriver/DFA.pm +++ b/lib/Kratos/DFADriver/DFA.pm @@ -6,6 +6,7 @@ use 5.020; use parent 'Class::Accessor'; +use Data::Dumper; use FLAT::DFA; use Math::Cartesian::Product; @@ -65,7 +66,21 @@ sub dfa { $dfa->set_accepting( $dfa->get_states ); for my $transition ( $self->model->transitions ) { - my $destination = $transition->{destination}; + print Dumper( $transition->{parameters} ); + + for my $param ( @{ $transition->{parameters} } ) { + if ( not defined $param->{values} ) { + die( +"argument values for transition $transition->{name} are undefined\n" + ); + } + if ( @{ $param->{values} } == 0 ) { + die( +"argument-value list for transition $transition->{name} is empty \n" + ); + } + } + my @argtuples = cartesian { 1 } map { $_->{values} } @{ $transition->{parameters} }; @@ -73,7 +88,8 @@ sub dfa { # an empty array if @{$transition->{parameters}} is empty for my $argtuple (@argtuples) { - for my $origin ( @{ $transition->{origins} } ) { + for my $transition_pair ( @{ $transition->{transitions} } ) { + my ( $origin, $destination ) = @{$transition_pair}; $dfa->add_transition( $self->model->get_state_id($origin), $self->model->get_state_id($destination), diff --git a/lib/Kratos/DFADriver/Model.pm b/lib/Kratos/DFADriver/Model.pm index 216f3b8..264a443 100644 --- a/lib/Kratos/DFADriver/Model.pm +++ b/lib/Kratos/DFADriver/Model.pm @@ -74,32 +74,57 @@ sub new_from_repo { for my $function ( values %{ $class_base->{function} } ) { my %param_values; for my $attrib ( @{ $function->{attributes} // [] } ) { - if ( $attrib =~ s{ ^ src _ }{}x ) { - push( @states, $attrib ); - push( @{ $transition{ $function->{name} }{src} }, $attrib ); - } - elsif ( $attrib =~ s{ ^ dst _ }{}x ) { - push( @states, $attrib ); - push( @{ $transition{ $function->{name} }{dst} }, $attrib ); - } - elsif ( $attrib =~ s{ ^ required_in_ }{}x ) { - push( - @{ - $self->{custom_code}{after_transition_by_state}{$attrib} - }, - $function->{name} - ); + if ( $attrib->{namespace} eq 'Model' ) { + if ( $attrib->{name} =~ m{ ^ transition }x + and @{ $attrib->{args} } == 2 ) + { + push( @states, $attrib->{args}[0]{expression} ); + push( @states, $attrib->{args}[1]{expression} ); + push( + @{ $transition{ $function->{name} }{src} }, + $attrib->{args}[0]{expression} + ); + push( + @{ $transition{ $function->{name} }{dst} }, + $attrib->{args}[1]{expression} + ); + push( + @{ $transition{ $function->{name} }{transitions} }, + [ + $attrib->{args}[0]{expression}, + $attrib->{args}[1]{expression} + ] + ); + } + elsif ( $attrib->{name} =~ m{ ^ testval }x + and @{ $attrib->{args} } == 2 ) + { + push( + @{ $param_values{ $attrib->{args}[0]{value} } }, + $attrib->{args}[1]{value} + ); + } + elsif ( + $attrib->{name} =~ m{ ^ required_in_ (?<state> .* ) $ }x ) + { + push( + @{ + $self->{custom_code}{after_transition_by_state} + { $+{state} } + }, + $function->{name} + ); + } + else { + printf( "wat %s::%s\n", + $attrib->{namespace}, $attrib->{name} ); + } } elsif ( $attrib =~ m{ ^ epilogue $ }x ) { $transition{ $function->{name} }{level} = 'epilogue'; } - elsif ( $attrib - =~ m{ ^ testarg _ (?<index> [^_]+ ) _ (?<value> [^_]+) $ }x ) - { - push( @{ $param_values{ $+{index} } }, $+{value} ); - } else { - say "wat $attrib"; + printf( "wat %s::%s\n", $attrib->{namespace}, $attrib->{name} ); } } if ( exists $transition{ $function->{name} } ) { @@ -160,22 +185,30 @@ sub new_from_repo { my @transition_names = sort keys %transition; for my $i ( 0 .. $#transition_names ) { - my $name = $transition_names[$i]; - my $guess_level = ( $name eq 'epilogue' ? 'epilogue' : 'user' ); + + my $name = $transition_names[$i]; + my @origins = uniq @{ $transition{$name}{src} }; + my @destinations = uniq @{ $transition{$name}{dst} }; + my $guess_level = ( $name eq 'epilogue' ? 'epilogue' : 'user' ); + $self->{transition}{$name} = { name => $name, id => $i, - destination => $transition{$name}{dst}[0], - origins => $transition{$name}{src}, + destination => \@destinations, + origins => \@origins, + transitions => $transition{$name}{transitions}, level => $transition{$name}{level} // $guess_level, parameters => $transition{$name}{parameters} // [], + duration => { static => 0 }, energy => { static => 0 }, rel_energy_prev => { static => 0 }, rel_energy_next => { static => 0 }, + timeout => { static => 0 }, }; - if ( @{ $transition{$name}{dst} } > 1 ) { + if ( @destinations > 1 ) { + my $dst_str = join( q{, }, @destinations ); warn( -"Transition ${name} has several destination states. This is not supported yet.\n" +"Transition ${name} has several destination states ($dst_str). This is only partially supported.\n" ); } } |