Esempio n. 1
0
    /**
     * Main visit function
     *
     * Visit function to process an automaton (directed, cyclic, discontinuous 
     * graph). No more detailed methods are defined, since the process of 
     * visiting is highly dependent on the concrete visitor implementation.
     *
     * Optionally labels may be passed for each node in the graph, which might 
     * be used during the rendering process.
     *
     * Returns a string, containing a DOT specification of the graph, to be 
     * rendered with graphviz.
     * 
     * @param slAutomaton $automaton
     * @param array $labels
     * @return string
     */
    public function visit(slAutomaton $automaton, array $labels = array())
    {
        $content = <<<EOSTYLE
digraph G 
{
    node [
        fontname  = Arial,
        fontcolor = "#2e3436",
        fontsize  = 10,

        style     = filled,
        color     = "#2e3436",
        fillcolor = "#babdb6",
        shape     = ellipse
    ];

    splines = true;
    overlap = false;

EOSTYLE;
        foreach ($automaton->getNodes() as $node) {
            $content .= sprintf("    \"%s\" [label = \"%s\"]\n", $node, isset($labels[(string) $node]) ? $labels[(string) $node] : $node);
        }
        $content .= "\n";
        foreach ($automaton->getNodes() as $node) {
            foreach ($automaton->getOutgoing($node) as $dst) {
                if ($automaton instanceof slTypeAutomaton) {
                    $content .= sprintf("    \"%s\" -> \"%s\" [label = \"%s\"]\n", $node, $dst, $automaton->getEdgeLabel($node, $dst));
                } else {
                    $content .= sprintf("    \"%s\" -> \"%s\"\n", $node, $dst);
                }
            }
        }
        return $content . "}\n";
    }
Esempio n. 2
0
 /**
  * Main visit function
  *
  * Visit function to process an automaton (directed, cyclic, discontinuous 
  * graph). No more detailed methods are defined, since the process of 
  * visiting is highly dependent on the concrete visitor implementation.
  *
  * Optionally labels may be passed for each node in the graph, which might 
  * be used during the rendering process.
  *
  * Returns an array with the support for each node, which just represents 
  * the number of incoming edges.
  * 
  * @param slAutomaton $automaton
  * @return array
  */
 public function visit(slAutomaton $automaton, array $labels = array())
 {
     $nodes = $automaton->getNodes();
     $ranks = array();
     foreach ($nodes as $node) {
         $ranks[$node] = count($automaton->getIncoming($node));
     }
     return $ranks;
 }
Esempio n. 3
0
 /**
  * Remove the given edge from the graph
  *
  * Removes the given edge from the graph, but keep the associated nodes.
  *
  * Returns false, if one of the nodes did not exist, and true otherwise.
  * 
  * @param string $src 
  * @param string $dst 
  * @return bool
  */
 public function removeEdge($src, $dst)
 {
     if (parent::removeEdge($src, $dst)) {
         unset($this->reverseEdges[(string) $dst][(string) $src]);
         return true;
     }
     return false;
 }
Esempio n. 4
0
 /**
  * Main visit function
  *
  * Visit function to process an automaton (directed, cyclic, discontinuous 
  * graph). No more detailed methods are defined, since the process of 
  * visiting is highly dependent on the concrete visitor implementation.
  *
  * Optionally labels may be passed for each node in the graph, which might 
  * be used during the rendering process.
  *
  * Returns an array with values for each node, representing their "imporance" 
  * in the graph based on Googles PageRank algorithm.
  * 
  * @param slAutomaton $automaton
  * @return array
  */
 public function visit(slAutomaton $automaton, array $labels = array())
 {
     $nodes = $automaton->getNodes();
     $ranks = array();
     foreach ($nodes as $node) {
         $ranks[$node] = 1;
     }
     for ($i = 0; $i < $this->iterations; ++$i) {
         foreach ($nodes as $node) {
             $rank = 0;
             foreach ($automaton->getIncoming($node) as $src) {
                 $pr = $ranks[$src];
                 $c = count($automaton->getOutgoing($src));
                 $rank += $pr / $c;
             }
             $ranks[$node] = 1 - $this->dampingFactor + $this->dampingFactor * $rank;
         }
     }
     return $ranks;
 }
Esempio n. 5
0
 /**
  * Merge singleton nodes
  *
  * All equivalency classes which consist of just one nodes are considered 
  * singleton nodes. This method merges all maximum sets of singleton nodes, 
  * which share the same successors and precedessors.
  * 
  * @param slAutomaton $automaton 
  * @return void
  */
 protected function mergeSingletonNodes(slAutomaton $automaton)
 {
     $classes = array_keys($this->equivalenceClasses);
     $classCount = count($classes);
     for ($i = 0; $i < $classCount; ++$i) {
         if (!isset($this->equivalenceClasses[$classes[$i]]) || count($this->equivalenceClasses[$classes[$i]]) > 1) {
             // We only care for singletons
             continue;
         }
         for ($j = $i + 1; $j < $classCount; ++$j) {
             if (!isset($this->equivalenceClasses[$classes[$j]]) || count($this->equivalenceClasses[$classes[$j]]) > 1) {
                 // We only care for singletons
                 continue;
             }
             if ($automaton->getOutgoing($classes[$i]) === $automaton->getOutgoing($classes[$j]) && $automaton->getIncoming($classes[$i]) === $automaton->getIncoming($classes[$j])) {
                 $this->equivalenceClasses[$classes[$i]][] = $classes[$j];
                 unset($this->equivalenceClasses[$classes[$j]]);
                 $automaton->removeNode($classes[$j]);
             }
         }
     }
 }
Esempio n. 6
0
 /**
  * Merge current automaton with given automaton
  * 
  * @param slAutomaton $automaton 
  * @return void
  */
 public function merge(slAutomaton $automaton)
 {
     foreach ($automaton->getNodes() as $identifier => $node) {
         if (!isset($this->nodes[$identifier])) {
             $this->addNode($node);
         }
     }
     foreach ($automaton->getNodes() as $identifier => $node) {
         foreach ($automaton->getOutgoing($node) as $dst) {
             $this->addEdge($node, $dst);
         }
     }
 }