|
From: notifies s. of c. c. <per...@li...> - 2007-02-26 13:32:00
|
Revision: 106
http://svn.sourceforge.net/perl-flat/?rev=106&view=rev
Author: estrabd
Date: 2007-02-26 05:31:56 -0800 (Mon, 26 Feb 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/perl-flat/dev-scripts/bdetest.pl
trunk/perl-flat/lib/FLAT/DFA.pm
Modified: trunk/perl-flat/dev-scripts/bdetest.pl
===================================================================
--- trunk/perl-flat/dev-scripts/bdetest.pl 2007-02-23 22:42:52 UTC (rev 105)
+++ trunk/perl-flat/dev-scripts/bdetest.pl 2007-02-26 13:31:56 UTC (rev 106)
@@ -8,4 +8,4 @@
use FLAT::Regex::WithExtraOps;
my $dfa = FLAT::Regex::WithExtraOps->new($ARGV[0])->as_pfa->as_nfa->as_dfa->as_min_dfa->trim_sinks;
-$dfa->depth_first();
+$dfa->acyclic();
Modified: trunk/perl-flat/lib/FLAT/DFA.pm
===================================================================
--- trunk/perl-flat/lib/FLAT/DFA.pm 2007-02-23 22:42:52 UTC (rev 105)
+++ trunk/perl-flat/lib/FLAT/DFA.pm 2007-02-26 13:31:56 UTC (rev 106)
@@ -2,8 +2,8 @@
use strict;
use base 'FLAT::NFA';
use Carp;
+$|++;
-
sub set_starting {
my $self = shift;
$self->SUPER::set_starting(@_);
@@ -175,9 +175,8 @@
return %node;
}
-# does a dft of digraph, but does not return a tree
-sub depth_first {
- use Sub::Recursive;
+# finds all acyclic s->f paths (f \in F)
+sub acyclic {
my $self = shift;
# data structure to do dft over
my %nodes = $self->as_node_list();
@@ -186,35 +185,33 @@
my %low = (); # "global" lookup table for low
my $lastDFLabel = 0;
my $recurse_level = 0; # tracks recurse level
+ my @string = ();
+ # anonymous, recursive function
+ use Sub::Recursive;
my $search = recursive {
my $startNode = shift;
$recurse_level++; # <- tracker
+# tree edge detection
if (!exists($dflabel{$startNode})) {
$dflabel{$startNode} = ++$lastDFLabel; # the order inwhich this link was explored
$low{$startNode} = $lastDFLabel;
$backtracked{$startNode} = 0; # marks this node as visited before - for cross edge detection
foreach my $adjacent (keys(%{$nodes{$startNode}})) {
- #printf("%s",$nodes{$startNode}{$adjacent}->[0]);
- #print "" if ($self->is_accepting($adjacent));
if (!exists($dflabel{$adjacent})) { # initial tree edge
-# print "tree edge! $startNode -> $adjacent"; # for testing only
- } elsif (-1 == ($dflabel{$adjacent} - $dflabel{$startNode})){ # detects child visiting a parent
-# print "tree edge, 2nd visit! $startNode is child of $adjacent!\n"; # for testing only
- } elsif ($dflabel{$adjacent} < $dflabel{$startNode}) { # back edge
-# print "back edge!";
- } elsif ($dflabel{$adjacent} < $dflabel{$startNode}) { # back edge
-# print "back edge, 2nd visit!\n";
+ push(@string,$nodes{$startNode}{$adjacent}->[0]);
+ $REC->($adjacent);
+ $backtracked{$adjacent}++; # <- track backtracked nodes
+ if ($low{$startNode} > $low{$adjacent}) {
+ $low{$startNode} = $low{$adjacent};
+ }
}
- $REC->($adjacent);
- # on back tracking, do the following
- $backtracked{$adjacent}++; # <- track backtracked nodes
- print "$backtracked{$adjacent}";
- # update LOW of $startNode
- if ($low{$startNode} > $low{$adjacent}) {
- $low{$startNode} = $low{$adjacent};
- }
+ print join('',@string) if ($self->is_accepting($adjacent));
+ pop(@string);
}
}
+ # remove startNode entry to facilitate acyclic path determination
+ delete($dflabel{$startNode});
+ $lastDFLabel--;
$recurse_level--; # <- tracker
return;
};
@@ -223,9 +220,11 @@
return;
}
-# returns a tree stucture resulting from a dft of the DFA;
-sub as_depth_first_tree {
- use Sub::Recursive;
+# does a dft of digraph, but does not return a tree
+# incorporates strong component detection, which I
+# think might yield some interesting methods for
+# generating valid strings
+sub depth_first {
my $self = shift;
# data structure to do dft over
my %nodes = $self->as_node_list();
@@ -234,62 +233,53 @@
my %low = (); # "global" lookup table for low
my $lastDFLabel = 0;
my $recurse_level = 0; # tracks recurse level
+ # anonymous, recursive function
+ use Sub::Recursive;
my $search = recursive {
my $startNode = shift;
- my %treeNode; # initialize
$recurse_level++; # <- tracker
+# tree edge detection
if (!exists($dflabel{$startNode})) {
- print "Accepting Node $startNode Found" if ($self->is_accepting($startNode));
$dflabel{$startNode} = ++$lastDFLabel; # the order inwhich this link was explored
$low{$startNode} = $lastDFLabel;
$backtracked{$startNode} = 0; # marks this node as visited before - for cross edge detection
- # tree node "struct" - really a hash..
- %treeNode = (
- node => $startNode,
- parent => undef,
- left => undef,
- right => undef,
- first => undef,
- last => undef,
- );
foreach my $adjacent (keys(%{$nodes{$startNode}})) {
+ #printf("%s",$nodes{$startNode}{$adjacent}->[0]);
+ #print "" if ($self->is_accepting($adjacent));
if (!exists($dflabel{$adjacent})) { # initial tree edge
-# print "tree edge! $startNode -> $adjacent\n"; # for testing only
- } elsif (-1 == ($dflabel{$adjacent} - $dflabel{$startNode})){ # detects child visiting a parent
-# print "tree edge, 2nd visit! $startNode is child of $adjacent!\n"; # for testing only
- } elsif ($dflabel{$adjacent} < $dflabel{$startNode}) { # back edge
-# print "back edge!";
- } elsif ($dflabel{$adjacent} < $dflabel{$startNode}) { # back edge
-# print "back edge, 2nd visit!\n";
- }
- my $child = $REC->($adjacent);
- if (defined($child)) {
- $child->{right} = undef;
- $child->{left} = undef;
- $child->{parent} = \%treeNode;
- if (!defined($treeNode{first})) {
- $treeNode{first} = $child;
- $treeNode{last} = $child;
- } else {
- $child->{left} = $treeNode{last};
- $treeNode{last}->{right} = $child;
- $treeNode{last} = $child;
+ print "tree edge! $startNode -> $adjacent"; # for testing only
+ $REC->($adjacent);
+ print "Backtracking $adjacent -> $startNode";
+ # on back tracking, do the following
+ $backtracked{$adjacent}++; # <- track backtracked nodes
+# print "$startNode -> $adjacent : $backtracked{$adjacent}";
+ # update LOW of $startNode
+ if ($low{$startNode} > $low{$adjacent}) {
+ $low{$startNode} = $low{$adjacent};
+ }
+ # detect strong component
+ if ($low{$adjacent} == $dflabel{$adjacent}) {
+ print "STRONG COMPONENT";
}
- }
- }
- $backtracked{$startNode}++; # <- track backtracked nodes
- # leave
- $recurse_level--; # <- tracker
- return \%treeNode;
+# back edge detection
+ } elsif ($dflabel{$adjacent} < $dflabel{$startNode} && !exists($backtracked{$adjacent})) { # back edge
+ print "back edge! $startNode -> $adjacent";
+# cross edge detection
+ } elsif ($backtracked{$adjacent}) {
+ print "cross edge! $startNode -> $adjacent";
+ # update low(startNode) with dflabel(adjacent) if low is greater than dflabel
+ if ($dflabel{$adjacent} < $low{$startNode}) {
+ $low{$startNode} = $dflabel{$adjacent};
+ }
+ }
+ }
}
$recurse_level--; # <- tracker
- return undef;
+ return;
};
-
- # start the recursive dft search
- my $tree = $search->($self->get_starting());
- # return tree
- return $tree;
+ # start the recursive dft search off
+ $search->($self->get_starting());
+ return;
}
# creates table used by a FLAT::DFA::Validator object to assess
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|