Get the precision ref from XBRL instance
@param DOMXPathNavigator $fact
@return bool
@throws \Exception
555235
public static function isItem( $fact )
	{
		$prefix = \XBRL_Types::getInstance()->getPrefixForNamespace( $fact->getNamespaceURI() );
		$name = "{$prefix}:{$fact->getLocalName()}";
		$element = \XBRL_Types::getInstance()->getElement( $name);
		if ( ! $element || ! isset( $element['substitutionGroup'] ) ) return false;

		$result = \XBRL_Types::getInstance()->resolveToSubstitutionGroup( $element['substitutionGroup'] , array( "xbrli:item" ) );
		return $result;
	}
793563
private function formatSexRecord(Fact $fact): string
    {
        $individual = $fact->record();

        switch ($fact->value()) {
            case 'M':
                $sex = I18N::translate('Male');
                break;
            case 'F':
                $sex = I18N::translate('Female');
                break;
            default:
                $sex = I18N::translateContext('unknown gender', 'Unknown');
                break;
        }

        $container_class = 'card';
        if ($fact->isPendingDeletion()) {
            $container_class .= ' old';
        } elseif ($fact->isPendingAddition()) {
            $container_class .= ' new';
        }

        if ($individual->canEdit()) {
            $edit_links = '<a class="btn btn-link" href="' . e(route('edit-fact', ['xref' => $individual->xref(), 'fact_id' => $fact->id(), 'ged' => $individual->tree()->name()])) . '" title="' . I18N::translate('Edit the gender') . '">' . view('icons/edit') . '<span class="sr-only">' . I18N::translate('Edit the gender') . '</span></a>';
        } else {
            $edit_links = '';
        }

        return '
		<div class="' . $container_class . '">
			<div class="card-header" role="tab" id="name-header-add">
				<div class="card-title mb-0">
					<b>' . I18N::translate('Gender') . '</b> ' . $sex . $edit_links . '
				</div>
			</div>
		</div>';
    }
712884
public function getValue( $variableSet, $evaluationResult, $log )
	{
		$sourceFact = $this->getSourceFact( $variableSet, $evaluationResult, $log );
		if ( ! $sourceFact )
		{
			$log->formula_validation( "Concept aspect rule", "No valid concept can be located",
				array(
					'source' => $this->qname
									? (string)(new QName( $this->qname['originalPrefix'], $this->qname['namespace'], $this->qname['name']) )
									: $this->qnameExpression,
					'error' => 'xbrlfe:missingConceptRule'
				)
			);
			return null;
		}

		return $sourceFact;
	}
1152359
protected function queryIsDone()
    {
        $result = false;

        $statReplyString = $this->fetchURL($this->pazpar2StatURL());
        $statReply = GeneralUtility::xml2array($statReplyString);

        if ($statReply) {
            // The progress variable is a string representing a number between
            // 0.00 and 1.00.
            // Casting it to int gives 0 as long as the value is < 1.
            $progress = (int)$statReply['progress'];
            $result = ($progress === 1);
            if ($result === true) {
                // We are done: note that and get the record count.
                $this->setDidRun(true);
                $this->setTotalResultCount($statReply['hits']);
            }
        } else {
            GeneralUtility::devLog('could not parse pazpar2 stat reply', 'pazpar2', 3);
        }

        return $result;
    }
720302
public function getResult(bool $wrap)
    {
        $rc = $this->factory->getProxy($this->val, $this->signature, $this->exception, $wrap);

        $factory = $this->factory;
        $this->factory = $this->client->simpleFactory;
        if ($rc instanceof \Soluble\Japha\Bridge\Driver\Pjb62\Exception\JavaException) {
            $factory->checkResult($rc);
        }

        return $rc;
    }
1239281
private function getUnitAspectValue( $source, $evaluationResult, $log )
	{
		// Get the unit from the source
		if ( is_null( $this->unitRule ) )
		{
			if ( ! $this->source )
			{
				return false;
			}

			$sourceFact = $this->getSourceFactWithErrorLogging( $source, $evaluationResult, ASPECT_UNIT, $log );
			$unitRef = FactValues::getUnitRef( $sourceFact );

			if ( ! $unitRef ) return null;

			// TODO What is in the $unit array
			$unit = $this->xbrlInstance->getUnit( $unitRef );
			return array( $unitRef => $unit );
		}
		else
		{
			/**
			 * @var Unit $unit
			 */
			$unit = Unit::fromArray( $this->unitRule );
			// This function will throw an exception if there is a problem so there is no return value to check
			$this->checkSAVConflicts( $unit->source, ASPECT_UNIT, $evaluationResult, $log );
			return $unit->getValue( $this, $evaluationResult, $log );
		}

	}
247877
public static function precision(int $tp, int $fp) : float
    {
        return $tp / (($tp + $fp) ?: EPSILON);
    }
306413
public function getRound( $precision = 0, $mode = PHP_ROUND_HALF_UP )
	{
		if ( $this->getIsDecimal() === false )
		{
			// return $this;
		}

		if ( $precision === false ) $precision = $this->scale( $this->_value );
		if ( is_null( $precision ) ) $precision = 0;
		// if( $precision < 0) $precision = 0;

		$factor = 1;

		// If the precision is negative create a factor
		if ( $precision < 0 )
		{
			$precision = abs( $precision );
			$factor = bcpow( 10, $precision, $precision );
			$precision = 0;
		}

		// Create a new decimal on which to perform rounding
		$rounder = $this->Div( $factor );

		$isHalf = false;
		$increment = "0";
		$number = $rounder->_value;
		$sign = "";

		if ( $mode == PHP_ROUND_HALF_EVEN || $mode == PHP_ROUND_HALF_ODD )
		{
			// These are only relevant if the precision rounds the least significant digit and that digit is 5.
			if ( $rounder->getDecimalIsHalf( $precision ) )
			{
				$isHalf = true;

				if ( $precision - 1 >= 0 )
				// if ( $this->getIntegerPart() != 0 )
				{
					if ( $rounder->getIsDecimalEven( $precision - 1) )
					{
						if ( $mode == PHP_ROUND_HALF_ODD )
						{
							$sign = $rounder->getIsNegative() ? "-" : "";
							// The amount to add or substract is 1 at the digit position one above the $scale position
							// If the scale is zero then the value change is 1 or -1.  If the scale is 1 then the
							// change is 0.1 or -0.1.
							$increment = $sign . bcpow( 10, "-$precision", $precision );
						}
					}
					else
					{
						if ( $mode == PHP_ROUND_HALF_EVEN )
						{
							$sign = $rounder->getIsNegative() ? "-" : "";
							// The amount to add or substract is 1 at the digit position one above the $scale position
							// If the scale is zero then the value change is 1 or -1.  If the scale is 1 then the
							// change is 0.1 or -0.1.
							$increment = $sign . bcpow( 10, "-$precision", $precision );

						}
					}
				}
				else
				{
					if ( $rounder->getIsIntegerEven( $precision ) )
					{
						if ( $mode == PHP_ROUND_HALF_ODD )
						{
							$sign = $rounder->getIsNegative() ? -1 : 1;
							$increment = 1 * $sign;
						}
					}
					else
					{
						if ( $mode == PHP_ROUND_HALF_EVEN )
						{
							$sign = $rounder->getIsNegative() ? -1 : 1;
							$increment = 1 * $sign;
						}
					}
				}

			}
		}

		if ( $rounder->getIsNegative() && $mode == PHP_ROUND_HALF_UP )
		{
			$mode = PHP_ROUND_HALF_DOWN;
		// 	$mode = $mode == PHP_ROUND_HALF_UP
		// 		? PHP_ROUND_HALF_DOWN
		// 		: PHP_ROUND_HALF_UP;
		}

		// Round half-up or half-down according to the $mode
		if ( ! $isHalf && $rounder->getIsCloserToNext( $precision, $mode ) )
		{
			$decimalPart = $rounder->getDecimalPart();
			if ( strlen( $decimalPart > $precision ) )
			{
				$sign = $rounder->getIsNegative() ? "-" : "";
				// The amount to add or substract is 1 at the digit position one above the $scale position
				// If the scale is zero then the value change is 1 or -1.  If the scale is 1 then the
				// change is 0.1 or -0.1.
				$increment = $sign . bcpow( 10, "-$precision", $precision );
			}
		}

		$rounder = DecimalValue::FromValue( bcadd( $rounder->getValue(), $increment, $precision ) );
		if ( $factor > 1 )
		{
			$rounder = $rounder->Mul( $factor );
		}

		return $rounder;
		// return new DecimalValue( $number );
	}
109533
public function Equals( $x, $y )
	{
		$nav1 = $x instanceof XPathNavigator
			? $x
			: null;
		$nav2 = $y instanceof XPathNavigator
			? $x
			: null;
		/**
		 * @var XPathNavigator $nav1
		 * @var XPathNavigator $nav2
		 */
		if ( ! is_null( $nav1 ) && ! is_null( $nav2 ) )
			return $nav1->IsSamePosition( $nav2 );
		else
			throw XPath2Exception::withErrorCodeAndParams( "XPTY0004", Resources::XPTY0004,
				array(
					"$xs:anyAtomicType",
					"node()* in function op:union,op:intersect and op:except"
				)
			);
	}
118087
public function resourceElementName()
	{
		if ( $this->isFactVar ) return "Fact Variable";
		else if ( $this->isGeneralVar ) return "General Variable";
		else if ( $this->isParameter ) return "Parameter";
		else if ( $this->var instanceof Tuple ) return "Tuple";
		else if ( $this->var instanceof Formula ) return "Formula";
		else if ( $this->var instanceof ValueAssertion ) return "ValueAssertion";
		else if ( $this->var instanceof ExistenceAssertion ) return "ExistenceAssertion";
		return false;
	}
925681
public static function formatFactPlaceShort(\Fisharebest\Webtrees\Fact $fact, $format, $anchor=false){
		$html='';
		
		if ($fact === null) return $html;
		$place = $fact->getPlace();
		if($place){
			$dplace = new Place($place);
			$html .= $dplace->htmlFormattedName($format, $anchor);
		}
		return $html;
	}
541447
public function getBool($prop) {

			// Get property
			$val = $this->get($prop);

			// String/numeric bool?
			if ($val === 'false') { 
				$val = false; 
			} elseif ($val === 'true') {
				$val = true;
			} elseif ($val === 1 || $val === '1') {
				$val = true;
			} elseif ($val === 0 || $val === '0') {
				$val = false;
			}




			// Boolean?
			if (is_bool($val))  {
				return $val;
			} else {
				return null;
			}

		}
1136425
private function getSourceFact( $variableSet, $evaluationResult, $log )
	{
		$sourceQName = null;

		if ( count( $this->qname ) )
		{
			$sourceQName = new QName( $this->qname[0]['originalPrefix'], $this->qname[0]['namespace'], $this->qname[0]['name'] );
			if ( ! $sourceQName ) return null;
		}
		elseif ( count( $this->qnameExpression ) )
		{
			$qname = $this->evaluateXPath( $variableSet, $this->qnameExpression[0], $evaluationResult['vars'] );
			if ( $qname instanceof XPath2Item )
			{
				$qname = $qname->getTypedValue();
			}
			if ( ! $qname ) return null;
			$sourceQName = new QName( $qname->Prefix, $qname->NamespaceUri, $qname->LocalName );
		}
		else
		{
			return null;
		}

		// OK, got the source fact but it might be a variable in which case the value of the variable will be required
		if ( isset( $variableSet->variablesByQName[ $sourceQName->clarkNotation() ] ) )
		{
			if ( ! isset( $evaluationResult['vars'][ $sourceQName->clarkNotation() ] ) )
			{
				$log->formula_validation( "Concept aspect", "Unable to find variable",
					array(
						'variable' => $sourceQName->clarkNotation(),
						'error' => 'xbrlfe:incompleteConceptRule'
					)
				);
			}
			// Get the evaluation value for this variable
			$fact = $evaluationResult['vars'][ $sourceQName->clarkNotation() ];
			if ( $fact instanceof XPath2NodeIterator )
			{
				// Get the first fact
				while (true)
				{
					foreach ( $fact as $node )
					{
						if ( ! $node instanceof DOMXPathNavigator ) continue;
						$fact = $node;
						break 2;
					}

					$fact = null;
					break;
				}
			}

			if ( $fact instanceof XPathNavigator )
			{
				$sourceQName = new QName( $fact->getPrefix(), $fact->getNamespaceURI(), $fact->getLocalName() );
			}
			else
			{
				$log->formula_validation( "Concept aspect", "The variable reference does not point to a result node",
					array(
						'variable' => $sourceQName->clarkNotation(),
						'error' => 'xbrlfe:incompleteConceptRule'
					)
				);
			}
		}
		return $sourceQName;
	}
753116
public function get($prop)
    {
        $value = isset($this->_data[$prop]) ? $this->_data[$prop] : null;

        // dereference property reference values
        return $value instanceof PropertyReference ? $value->value() : $value;
    }
768436
public function get_force_ltr() {
        $forceltr = parent::get_force_ltr();
        if ($forceltr === null) {
            return !is_rtl_compatible($this->paramtype);
        }
        return $forceltr;
    }
216907
public static function getProvisionalVersionForDimension(int $dimension) : self
    {
        if (1 !== $dimension % 4) {
            throw new InvalidArgumentException('Dimension is not 1 mod 4');
        }

        return self::getVersionForNumber(intdiv($dimension - 17, 4));
    }
604453
public function toQuery( $variableSet, $factVariableBinding )
	{
		/**
		 * These are the arguments to the xfi:concept-relationships function
	     * #source
		 * #linkrole
		 * #arcrole
		 * #axis
		 * #generations
		 * #linkname
		 * #arcname
		 */

		$source = $this->variable
					? ( "fn:node-name(" . ( $this->variable['originalPrefix'] ? "\${$this->variable['originalPrefix']}:$this->variable['name']" : "\${$this->variable['name']}" ) . ")" )
					: ( $this->qnameExpression
							? $this->qnameExpression
							: "QName('" . qname($this->qname, $variableSet->nsMgr->getNamespaces())->namespaceURI . "', '" . qname($this->qname, $variableSet->nsMgr->getNamespaces())->localName . "')"
					  );

		$linkrole = $this->linkrole
					? "'{$this->linkrole}'"
					: ( $this->linkroleExpression
							? $this->linkroleExpression
							: "()"
					  );

		$arcrole = $this->arcrole
					? "'{$this->arcrole}'"
					: ( $this->arcroleExpression
							? $this->arcroleExpression
							: "()"
					  );

		$axis = "{$this->axis}";
		$generations = $this->generations ? $this->generations : "()";

		$linkname = $this->linkname
					? "'{$this->linkname}'"
					: ( $this->linknameExpression
							? $this->linknameExpression
							: "()"
					  );

		$arcname = $this->arcname
					? "'{$this->arcname}'"
					: ( $this->arcnameExpression
							? $this->arcnameExpression
							: "()"
					  );

		$test = $this->test
					? $this->test
					: "true()";

		// Alternative line end goes here (for query formatting)
		$le = "";

		$query = "( $le" .
				 "	( $le" .
				 "		some \$relationship in $le" .
				 "			xfi:concept-relationships( $le" .
				 "				$source, $le" .
				 "				$linkrole, $le" .
				 "				$arcrole, $le" .
				 "				" . str_replace( "-or-self", "", "'$axis'" ) . ",$le" .
		//		 "				fn:replace($axis,'-or-self',''), $le" .
				 "				$generations, $le" .
				 "				$linkname, $le" .
				 "				$arcname $le" .
				 "			) $le" .
				 "		satisfies $le" .
				 "			( $le" .
				 "				\$relationship[$test] and $le" .
				 "				(fn:node-name(.) eq $le" .
             	 "					( $le" .
             	 "						if (matches('$axis','ancestor|parent')) $le" .
              	 "						then xfi:relationship-from-concept(\$relationship) $le" .
              	 "						else xfi:relationship-to-concept(\$relationship) $le" .
              	 "					) $le" .
              	 "				) $le" .
              	 "			) $le" .
              	 "  ) $le";

		$clause1 = "" .
				 "	or $le" .
				 "	( $le" .
		//		 "		fn:starts-with($axis,'sibling') and $le" .
				 "		fn:empty( $le" .
				 "			xfi:concept-relationships( $source, $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		fn:empty( $le" .
				 "			xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		fn:exists( $le" .
				 "			xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'child', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		(fn:node-name(.) ne $source) $le" .
				 "	) $le";

		$clause2 = "" .
				 "	or $le" .
				 "	( $le" .
		//		 "		fn:ends-with($axis,'-or-self') $le" .
		//		 " 		and $le" .
		//		 "		( $le" .
				 "			if ( QName('http://www.xbrl.org/2008/function/instance','root') eq $source) $le" .
				 "			then $le" .
				 "			( $le" .
				 "				fn:empty( $le" .
				 "					xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "				) and $le" .
				 "				fn:exists( $le" .
				 "					xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'child', 1, $linkname, $arcname) $le" .
				 "				) $le" .
				 "			) $le" .
				 "			else $le" .
				 "			( $le" .
				 "				fn:node-name(.) eq $source $le" .
				 "			) $le" .
		//		 "		) $le" .
				 "  ) $le";

		$query = $query . ( \XBRL::startsWith( $axis, 'sibling' ) ? $clause1 : "" ) . ( \XBRL::endsWith( $axis, '-or-self' ) ? $clause2 : "" );
		$query .= ") $le";
		if ( empty( $le ) )
		{
			$query = preg_replace( "/\s\t+/", " ", $query );
		}
		echo $query;
		return $query;
	}