Algorithm-ConstructDFA2
view release on metacpan or search on metacpan
lib/Algorithm/ConstructDFA2.pm view on Meta::CPAN
$self->_dbh->commit();
return $state_id;
}
sub _vertex_str_from_partial_list {
my ($self, @vertices) = @_;
return $self->_vertex_str_from_vertices() unless @vertices;
my $escaped_roots = join ", ", map {
$self->_dbh->quote($_)
} @vertices;
my ($vertex_str) = $self->_dbh->selectrow_array(qq{
SELECT _canonical(json_group_array(closure.e_reachable))
FROM Closure
WHERE root IN ($escaped_roots)
});
return $vertex_str;
}
sub find_or_create_state_id {
my ($self, @vertices) = @_;
my $vertex_str = _vertex_str_from_partial_list($self, @vertices);
return _find_or_create_state_from_vertex_str($self, $vertex_str);
}
sub vertices_in_state {
my ($self, $state_id) = @_;
return map { @$_ } $self->_dbh->selectall_array(q{
SELECT vertex FROM Configuration WHERE state = ?
}, {}, $state_id);
}
sub cleanup_dead_states {
my ($self, $vertices_accept) = @_;
$self->_dbh->sqlite_create_function( '_vertices_accept', 1, sub {
my @vertices = $self->_vertex_str_to_vertices(@_);
return !! $vertices_accept->(@vertices);
});
$self->_dbh->begin_work();
$self->_dbh->do(q{
CREATE TEMPORARY TABLE accepting AS
SELECT state_id AS state
FROM State
WHERE _vertices_accept(vertex_str)+0 = 1
});
my @accepting = map { @$_ } $self->_dbh->selectall_array(q{
SELECT state FROM accepting
});
# NOTE: this also renames states in transitions involving
# possible start states, but they would then simply have no
# transitions, which should be fine.
$self->_dbh->do(q{
WITH RECURSIVE all_living(state) AS (
SELECT state FROM accepting
UNION
SELECT src AS state
FROM Transition
INNER JOIN all_living
ON (Transition.dst = all_living.state)
)
UPDATE Transition
SET dst = ?
WHERE dst NOT IN (SELECT state FROM all_living)
}, {}, $self->dead_state_id);
$self->_dbh->do(q{
DROP TABLE accepting;
});
$self->_dbh->commit();
# TODO: is there a better way to drop the function?
$self->_dbh->sqlite_create_function( '_vertices_accept', 1, undef );
return @accepting;
}
sub compute_some_transitions {
my ($self, $limit) = @_;
$limit //= 1_000;
my $sth = $self->_dbh->prepare_cached(q{
SELECT
s.state_id AS src
, i.value AS input
, _canonical(json_group_array(closure.e_reachable))
AS dst_vertex_str
FROM
state s
CROSS JOIN input i
LEFT JOIN configuration c
ON (s.state_id = c.state)
LEFT JOIN match m
ON (m.vertex = c.vertex AND m.input = i.value)
LEFT JOIN edge
ON (m.vertex = edge.src)
LEFT JOIN closure
ON (edge.dst = closure.root)
LEFT JOIN transition t
ON (t.src = s.state_id AND t.input = i.value)
WHERE
t.dst IS NULL
GROUP BY
s.state_id, i.rowid
ORDER BY
( run in 1.900 second using v1.01-cache-2.11-cpan-5735350b133 )