Inheritance: extends Gliph\Graph\Graph
Exemplo n.º 1
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($graph->inDegreeOf($vertex) === 0 && !$vertex instanceof Vertex\Function_) {
         Helper::remove($vertex, $graph);
         return true;
     }
     return false;
 }
Exemplo n.º 2
0
 public function countUsages(Variable $var, Digraph $graph)
 {
     $counter = 0;
     foreach ($graph->vertices() as $vtx) {
         if (in_array($var, $vtx->getVariables(), true)) {
             $counter++;
         }
     }
     return $counter;
 }
Exemplo n.º 3
0
 /**
  * Convert a Graph to a phpDocumentor graph, usable for printing
  *
  * @param \Gliph\Graph\Digraph $graph The graph to print
  *
  * @return \phpDocumentor\GraphViz\Graph The copied graph
  */
 protected function convertGraph(Digraph $graph)
 {
     $new = Graph::create("dump");
     $nodes = new \SplObjectStorage();
     $ctr = 0;
     foreach ($graph->vertices() as $vertex) {
         $nodes[$vertex] = Node::create('node_' . $ctr++, (string) $vertex);
         $new->setNode($nodes[$vertex]);
     }
     foreach ($graph->edges() as $edge) {
         $new->link(Edge::create($nodes[$edge[0]], $nodes[$edge[1]]));
     }
     return $new;
 }
Exemplo n.º 4
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex instanceof Vertex\Phi) {
         $types = [];
         foreach ($vertex->getValues() as $value) {
             $types[] = (string) $value->getType();
         }
         $types = array_unique($types);
         if ($vertex->getResult()->getType()->isUnknown()) {
             $type = null;
             $setAll = false;
             if (count($types) === 1 && $types[0] !== 'unknown') {
                 $type = Type::normalizeType($types[0]);
             } elseif (count($types) === 2 && in_array('long', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_LONG);
                 $setAll = true;
             } elseif (count($types) === 2 && in_array('double', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_DOUBLE);
                 $setAll = true;
             } elseif (count($types) === 2 && in_array('bool', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_BOOLEAN);
             }
             if ($type) {
                 $vertex->getResult()->setType($type);
                 if ($setAll) {
                     foreach ($vertex->getValues() as $value) {
                         $value->setType($type);
                     }
                 }
                 return true;
             }
         }
         if (count($vertex->getValues()) === 1) {
             // remove phi node
             list($val) = iterator_to_array($vertex->getValues());
             $result = $vertex->getResult();
             foreach ($graph->vertices() as $vtx) {
                 $vtx->replaceVariable($result, $val);
                 if ($vtx instanceof Assignment && $vtx->getResult() === $result) {
                     $vtx->setResult($val);
                 }
             }
             Helper::remove($vertex, $graph);
             return true;
         }
     }
     return false;
 }
Exemplo n.º 5
0
 /**
  * Finds connected components in the provided directed graph.
  *
  * @param Digraph $graph
  *   The Digraph to search for connected components.
  * @param TarjanSCCVisitor $visitor
  *   The visitor that will collect and store the connected components. One
  *   will be created if not provided.
  *
  * @return TarjanSCCVisitor
  *   The finalized visitor.
  */
 public static function tarjan_scc(Digraph $graph, TarjanSCCVisitor $visitor = NULL)
 {
     $visitor = $visitor ?: new TarjanSCCVisitor();
     $counter = 0;
     $stack = array();
     $indices = new \SplObjectStorage();
     $lowlimits = new \SplObjectStorage();
     $visit = function ($vertex) use(&$visit, &$counter, $graph, &$stack, $indices, $lowlimits, $visitor) {
         $indices->attach($vertex, $counter);
         $lowlimits->attach($vertex, $counter);
         $stack[] = $vertex;
         $counter++;
         foreach ($graph->successorsOf($vertex) as $head) {
             if (!$indices->contains($head)) {
                 $visit($head);
                 $lowlimits[$vertex] = min($lowlimits[$vertex], $lowlimits[$head]);
             } else {
                 if (in_array($head, $stack, TRUE)) {
                     $lowlimits[$vertex] = min($lowlimits[$vertex], $indices[$head]);
                 }
             }
         }
         if ($lowlimits[$vertex] === $indices[$vertex]) {
             $visitor->newComponent();
             do {
                 $other = array_pop($stack);
                 $visitor->addToCurrentComponent($other);
             } while ($other != $vertex);
         }
     };
     foreach ($graph->vertices() as $v) {
         if (!$indices->contains($v)) {
             $visit($v);
         }
     }
     return $visitor;
 }
Exemplo n.º 6
0
 public static function isLiveVar(Variable $var, Vertex $vtx, Digraph $graph)
 {
     static $seen = [];
     if (in_array($vtx, $seen, true)) {
         return false;
     } elseif (in_array($var, $vtx->getVariables(), true)) {
         return true;
     }
     $seen[] = $vtx;
     foreach ($graph->successorsOf($vtx) as $sub) {
         if (self::isLiveVar($var, $sub, $graph)) {
             array_pop($seen);
             return true;
         }
     }
     array_pop($seen);
     return false;
 }
Exemplo n.º 7
0
 /**
  * Finds source vertices in a Digraph, then enqueues them.
  *
  * @param Digraph $graph
  * @param DepthFirstVisitorInterface $visitor
  *
  * @return \SplQueue
  */
 public static function find_sources(Digraph $graph, DepthFirstVisitorInterface $visitor)
 {
     $incomings = new \SplObjectStorage();
     $queue = new \SplQueue();
     foreach ($graph->edges() as $edge) {
         if (!isset($incomings[$edge[1]])) {
             $incomings[$edge[1]] = new \SplObjectStorage();
         }
         $incomings[$edge[1]]->attach($edge[0]);
     }
     // Prime the queue with vertices that have no incoming edges.
     foreach ($graph->vertices() as $vertex) {
         if (!$incomings->contains($vertex)) {
             $queue->push($vertex);
             $visitor->onInitializeVertex($vertex, TRUE, $queue);
         } else {
             $visitor->onInitializeVertex($vertex, FALSE, $queue);
         }
     }
     return $queue;
 }