src/VDB/Uri/Uri.php
private function resolveRelativeReference()
    {
        if (null !== $this->scheme) {
            $this->normalizeDotSegments();
        } else {
            $this->scheme = $this->baseUri->scheme;
            if (null !== $this->authority) {
                $this->normalizeDotSegments();
            } else {
                $this->authority = $this->baseUri->authority;
                $this->parseUserInfoHostPort();
                if ('' === $this->path) {
                    $this->path = $this->baseUri->path;
                    if (null === $this->query) {
                        $this->query = $this->baseUri->query;
                    }
                } else {
                    if (0 === strpos($this->path, '/')) {
                        $this->normalizeDotSegments();
                    } else {
                        $this->mergeBasePath();
                        $this->normalizeDotSegments();
                    }
                }
            }
        }
    }
private function resolveRelativeReference()
    {
        if (null !== $this->scheme) {
            $this->normalizeDotSegments();
        } else {
            $this->scheme = $this->baseUri->scheme;
            if (null !== $this->authority) {
                $this->normalizeDotSegments();
            } else {
                $this->authority = $this->baseUri->authority;
                $this->parseUserInfoHostPort();
                if ('' === $this->path) {
                    $this->path = $this->baseUri->path;
                    if (null === $this->query) {
                        $this->query = $this->baseUri->query;
                    }
                } else {
                    if (0 === strpos($this->path, '/')) {
                        $this->normalizeDotSegments();
                    } else {
                        $this->mergeBasePath();
                        $this->normalizeDotSegments();
                    }
                }
            }
        }
    }
private function resolveRelativeReference ( ) { if ( null !== $ this -> scheme ) { $ this -> normalizeDotSegments ( ) ; } else { $ this -> scheme = $ this -> baseUri -> scheme ; if ( null !== $ this -> authority ) { $ this -> normalizeDotSegments ( ) ; } else { $ this -> authority = $ this -> baseUri -> authority ; $ this -> parseUserInfoHostPort ( ) ; if ( '' === $ this -> path ) { $ this -> path = $ this -> baseUri -> path ; if ( null === $ this -> query ) { $ this -> query = $ this -> baseUri -> query ; } } else { if ( 0 === strpos ( $ this -> path , '/' ) ) { $ this -> normalizeDotSegments ( ) ; } else { $ this -> mergeBasePath ( ) ; $ this -> normalizeDotSegments ( ) ; } } } } }
From RFC 3986 paragraph 4.2

relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
relative-part = "//" authority path-abempty
/ path-absolute
/ path-noscheme
/ path-empty

then:

From RFC 3986 paragraph 5.2.2

For each Uri reference (R), the following pseudocode describes an
algorithm for transforming R into its target Uri (T):

-- The Uri reference is parsed into the five Uri components
--
(R.scheme, R.authority, R.path, R.query, R.fragment) = parse(R);

-- A non-strict parser may ignore a scheme in the reference
-- if it is identical to the base Uri's scheme.
--
if ((not strict) and (R.scheme == Base.scheme)) then
undefine(R.scheme);
endif;

if defined(R.scheme) then
T.scheme    = R.scheme;
T.authority = R.authority;
T.path      = remove_dot_segments(R.path);
T.query     = R.query;
else
if defined(R.authority) then
T.authority = R.authority;
T.path      = remove_dot_segments(R.path);
T.query     = R.query;
else
if (R.path == "") then
T.path = Base.path;
if defined(R.query) then
T.query = R.query;
else
T.query = Base.query;
endif;
else
if (R.path starts-with "/") then
T.path = remove_dot_segments(R.path);
else
T.path = merge(Base.path, R.path);
T.path = remove_dot_segments(T.path);
endif;
T.query = R.query;
endif;
T.authority = Base.authority;
endif;
T.scheme = Base.scheme;
endif;

T.fragment = R.fragment;
From RFC 3986 paragraph 4 . 2