public function checkForCircularReference(array $phiNodes, GraphState $state)
{
$graph = new DirectedAdjacencyList();
foreach ($phiNodes as $phi) {
$result = $phi->getResult();
foreach ($phi->getValues() as $value) {
$graph->ensureArc($value, $result);
}
}
$cycles = $graph->getCycles();
foreach ($cycles as $cycle) {
if ($this->areAllUnknown($cycle)) {
// All are unknown, process!
$types = array();
foreach ($cycle as $component) {
foreach (Helper::getInboundNodes($component, $graph) as $node) {
if (in_array($node, $cycle, true)) {
continue;
}
$types[] = $node->getType()->getType();
}
}
$types = array_unique($types);
$newType = 0;
switch (count($types)) {
case 1:
if ($types[0] != Type::TYPE_UNKNOWN) {
$newType = $types[0];
}
break;
case 2:
if (in_array(Type::TYPE_NUMERIC, $types) && in_array(Type::TYPE_LONG, $types)) {
$newType = Type::TYPE_NUMERIC;
} elseif (in_array(Type::TYPE_NUMERIC, $types) && in_array(Type::TYPE_DOUBLE, $types)) {
$newType = Type::TYPE_DOUBLE;
}
break;
}
if ($newType) {
foreach ($cycle as $component) {
$component->setType(new Type($newType));
}
return true;
}
}
}
return false;
}