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
 /**
  * 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. 4
0
 /**
  * Calculate equivalent nodes
  *
  * Calculate groups of nodes, which are contained in their respective 
  * transitive reflexive closure in the automaton.
  *
  * Returns an automaton consisting of nodes, which each links to such a 
  * node group.
  * 
  * @param slCountingSingleOccurenceAutomaton $automaton 
  * @return void
  */
 protected function calculateEquivalencyAutomaton(slAutomaton $automaton)
 {
     $nodeValues = $automaton->getNodes();
     $nodes = array_keys($nodeValues);
     $nodeCount = count($nodes);
     $equivalent = array();
     $skip = array();
     // Find equivalence classes in automaton
     for ($i = 0; $i < $nodeCount; ++$i) {
         if (isset($skip[$i])) {
             continue;
         }
         $this->equivalenceClasses[$nodes[$i]] = array($nodes[$i]);
         $equivalent[$nodes[$i]] = $nodes[$i];
         for ($j = $i + 1; $j < $nodeCount; ++$j) {
             if (in_array($nodes[$i], $automaton->transitiveClosure($nodes[$j])) && in_array($nodes[$j], $automaton->transitiveClosure($nodes[$i]))) {
                 $this->equivalenceClasses[$nodes[$i]][] = $nodes[$j];
                 $equivalent[$nodes[$j]] = $nodes[$i];
                 // The mutal containment in eachs reflexive transitive
                 // closure is obviously symetric
                 $skip[$j] = true;
             }
         }
     }
     // Readd edges between equivalency classes based on source automaton
     $equivalencyAutomaton = new slAutomaton();
     foreach ($this->equivalenceClasses as $name => $nodes) {
         $equivalencyAutomaton->addNode($name);
         foreach ($nodes as $node) {
             foreach ($automaton->getOutgoing($node) as $dst) {
                 if ($name !== $equivalent[$dst]) {
                     $equivalencyAutomaton->addEdge($name, $equivalent[$dst]);
                 }
             }
         }
     }
     return $equivalencyAutomaton;
 }
Esempio n. 5
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);
         }
     }
 }