def test_step(multipolygon_with_multisegment: Tuple[Multipolygon, Multisegment]
              ) -> None:
    multipolygon, multisegment = multipolygon_with_multisegment
    first_segment, rest_multisegment = multisegment_pop_left(multisegment)

    result = multisegment_in_multipolygon(rest_multisegment, multipolygon)
    next_result = multisegment_in_multipolygon(multisegment, multipolygon)

    relation_with_first_segment = segment_in_multipolygon(first_segment,
                                                          multipolygon)
    assert equivalence(next_result is Relation.DISJOINT,
                       result is relation_with_first_segment
                       is Relation.DISJOINT)
    assert implication(next_result is Relation.TOUCH,
                       result is Relation.TOUCH
                       and relation_with_first_segment is not Relation.CROSS
                       or result is Relation.DISJOINT
                       and relation_with_first_segment is Relation.TOUCH)
    assert implication(result is Relation.DISJOINT
                       and relation_with_first_segment is Relation.TOUCH
                       or result is Relation.TOUCH
                       and relation_with_first_segment is Relation.DISJOINT,
                       next_result is Relation.TOUCH)
    assert equivalence(next_result is Relation.CROSS,
                       result is Relation.CROSS
                       or relation_with_first_segment is Relation.CROSS
                       or (bool(rest_multisegment.segments)
                           and result is Relation.DISJOINT
                           or result is Relation.TOUCH)
                       and (relation_with_first_segment is Relation.ENCLOSED
                            or relation_with_first_segment is Relation.WITHIN)
                       or (result is Relation.ENCLOSED
                           or result is Relation.WITHIN)
                       and (relation_with_first_segment is Relation.DISJOINT
                            or relation_with_first_segment is Relation.TOUCH))
    assert equivalence(next_result is Relation.COMPONENT,
                       (not rest_multisegment.segments
                        or result is Relation.COMPONENT)
                       and relation_with_first_segment is Relation.COMPONENT)
    assert equivalence(next_result is Relation.ENCLOSED,
                       not rest_multisegment.segments
                       and relation_with_first_segment is Relation.ENCLOSED
                       or (result is Relation.COMPONENT
                           or result is Relation.ENCLOSED)
                       and (relation_with_first_segment is Relation.ENCLOSED
                            or relation_with_first_segment is Relation.WITHIN)
                       or (result is Relation.ENCLOSED
                           or result is Relation.WITHIN)
                       and relation_with_first_segment is Relation.COMPONENT
                       or result is Relation.WITHIN
                       and relation_with_first_segment is Relation.ENCLOSED)
    assert equivalence(next_result is Relation.WITHIN,
                       (not rest_multisegment.segments
                        or result is Relation.WITHIN)
                       and relation_with_first_segment is Relation.WITHIN)
def test_step(contour_with_multisegment: Tuple[Contour, Multisegment]) -> None:
    contour, multisegment = contour_with_multisegment
    first_segment, rest_multisegment = multisegment_pop_left(multisegment)

    result = multisegment_in_contour(rest_multisegment, contour)
    next_result = multisegment_in_contour(multisegment, contour)

    relation_with_first_segment = segment_in_contour(first_segment, contour)
    assert equivalence(
        next_result is Relation.DISJOINT,
        result is relation_with_first_segment is Relation.DISJOINT)
    assert implication(
        next_result is Relation.TOUCH, result is Relation.TOUCH and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH)
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH)
    assert implication(
        result is Relation.TOUCH
        and relation_with_first_segment is Relation.DISJOINT
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH,
        next_result is Relation.TOUCH)
    assert implication(
        next_result is Relation.CROSS, result is Relation.CROSS and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or (result is Relation.DISJOINT or result is Relation.TOUCH)
        and relation_with_first_segment is Relation.CROSS
        or result is Relation.TOUCH
        and relation_with_first_segment is Relation.TOUCH)
    assert implication(
        result is Relation.CROSS and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or (result is Relation.DISJOINT or result is Relation.TOUCH)
        and relation_with_first_segment is Relation.CROSS,
        next_result is Relation.CROSS)
    assert implication(
        next_result is Relation.OVERLAP, result is Relation.OVERLAP
        or relation_with_first_segment is Relation.OVERLAP
        or (result is Relation.DISJOINT and bool(rest_multisegment.segments)
            or result is Relation.TOUCH or result is Relation.CROSS)
        and relation_with_first_segment is Relation.COMPONENT
        or result is Relation.COMPONENT and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS))
    assert implication(
        next_result is Relation.COMPOSITE, result is Relation.COMPOSITE
        or relation_with_first_segment is Relation.COMPOSITE
        or bool(rest_multisegment.segments)
        and relation_with_first_segment is Relation.EQUAL
        or result is Relation.EQUAL or result is Relation.COMPONENT
        and relation_with_first_segment is Relation.OVERLAP
        or result is Relation.OVERLAP
        and relation_with_first_segment is Relation.COMPONENT)
    assert implication(
        result is Relation.COMPOSITE
        or relation_with_first_segment is Relation.COMPOSITE
        or bool(rest_multisegment.segments)
        and relation_with_first_segment is Relation.EQUAL
        or result is Relation.EQUAL, next_result is Relation.COMPOSITE)
    assert implication(
        next_result is Relation.EQUAL, not rest_multisegment.segments
        and relation_with_first_segment is Relation.EQUAL
        or result is relation_with_first_segment is Relation.COMPONENT)
    assert implication(
        not rest_multisegment.segments
        and relation_with_first_segment is Relation.EQUAL,
        next_result is Relation.EQUAL)
    assert implication(
        next_result is Relation.COMPONENT,
        (not rest_multisegment.segments or result is Relation.COMPONENT)
        and relation_with_first_segment is Relation.COMPONENT)
    assert implication(
        not rest_multisegment.segments
        and relation_with_first_segment is Relation.COMPONENT,
        next_result is Relation.COMPONENT)
def test_step(multisegments_pair: Tuple[Multisegment, Multisegment]) -> None:
    left, right = multisegments_pair
    first_segment, rest_left = multisegment_pop_left(left)

    result = multisegment_in_multisegment(rest_left, right)
    next_result = multisegment_in_multisegment(left, right)

    relation_with_first_segment = segment_in_multisegment(first_segment, right)
    assert equivalence(
        next_result is Relation.DISJOINT,
        result is relation_with_first_segment is Relation.DISJOINT)
    assert implication(
        next_result is Relation.TOUCH, result is Relation.TOUCH and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH)
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH)
    assert implication(
        result is Relation.TOUCH
        and relation_with_first_segment is Relation.DISJOINT
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH,
        next_result is Relation.TOUCH)
    assert implication(
        next_result is Relation.CROSS, result is Relation.CROSS and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or (result is Relation.DISJOINT or result is Relation.TOUCH)
        and relation_with_first_segment is Relation.CROSS
        or result is Relation.TOUCH
        and relation_with_first_segment is Relation.TOUCH)
    assert implication(
        result is Relation.CROSS and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or (result is Relation.DISJOINT or result is Relation.TOUCH)
        and relation_with_first_segment is Relation.CROSS,
        next_result is Relation.CROSS)
    assert implication(
        next_result is Relation.OVERLAP, result is Relation.OVERLAP
        or relation_with_first_segment is Relation.OVERLAP
        or (result is Relation.DISJOINT and bool(rest_left.segments)
            or result is Relation.TOUCH or result is Relation.CROSS)
        and relation_with_first_segment is Relation.COMPONENT
        or result is Relation.COMPONENT and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS))
    assert implication(
        next_result is Relation.COMPOSITE, result is Relation.COMPOSITE
        or relation_with_first_segment is Relation.COMPOSITE
        or result is Relation.OVERLAP and
        (relation_with_first_segment is Relation.COMPONENT
         or relation_with_first_segment is Relation.OVERLAP)
        or bool(rest_left.segments)
        and relation_with_first_segment is Relation.EQUAL
        or result is Relation.EQUAL or result is Relation.COMPONENT
        and relation_with_first_segment is Relation.OVERLAP)
    assert implication(
        result is Relation.COMPOSITE
        or relation_with_first_segment is Relation.COMPOSITE
        or bool(rest_left.segments)
        and relation_with_first_segment is Relation.EQUAL
        or result is Relation.EQUAL, next_result is Relation.COMPOSITE)
    assert implication(
        next_result is Relation.EQUAL, not rest_left.segments
        and relation_with_first_segment is Relation.EQUAL
        or result is relation_with_first_segment is Relation.COMPONENT)
    assert implication(
        not rest_left.segments
        and relation_with_first_segment is Relation.EQUAL,
        next_result is Relation.EQUAL)
    assert implication(next_result is Relation.COMPONENT,
                       (not rest_left.segments or result is Relation.COMPONENT)
                       and relation_with_first_segment is Relation.COMPONENT)
    assert implication(
        not rest_left.segments
        and relation_with_first_segment is Relation.COMPONENT,
        next_result is Relation.COMPONENT)
def test_step(multisegment_with_segment: Tuple[Multisegment, Segment]) -> None:
    multisegment, segment = multisegment_with_segment
    first_segment, rest_multisegment = multisegment_pop_left(multisegment)

    result = segment_in_multisegment(segment, rest_multisegment)
    next_result = segment_in_multisegment(segment, multisegment)

    relation_with_first_segment = segment_in_segment(segment, first_segment)
    assert equivalence(
        next_result is Relation.DISJOINT, result is Relation.DISJOINT
        and relation_with_first_segment is Relation.DISJOINT)
    assert implication(
        next_result is Relation.TOUCH, result is Relation.TOUCH and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH)
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH)
    assert implication(
        result is Relation.TOUCH
        and relation_with_first_segment is Relation.DISJOINT
        or result is Relation.DISJOINT
        and relation_with_first_segment is Relation.TOUCH,
        next_result is Relation.TOUCH)
    assert implication(
        next_result is Relation.CROSS, result is Relation.DISJOINT
        and relation_with_first_segment is Relation.CROSS
        or result is Relation.TOUCH and
        (relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or result is Relation.CROSS and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS))
    assert implication((result is Relation.DISJOINT or result is Relation.TOUCH
                        or result is Relation.CROSS)
                       and relation_with_first_segment is Relation.CROSS
                       or result is Relation.CROSS and
                       (relation_with_first_segment is Relation.DISJOINT
                        or relation_with_first_segment is Relation.TOUCH),
                       next_result is Relation.CROSS)
    assert implication(
        next_result is Relation.OVERLAP,
        (result is Relation.DISJOINT and rest_multisegment.segments
         or result is Relation.TOUCH or result is Relation.CROSS)
        and relation_with_first_segment is Relation.COMPOSITE
        or result is Relation.OVERLAP or result is Relation.COMPOSITE and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.OVERLAP)
        or relation_with_first_segment is Relation.OVERLAP)
    assert implication(
        (result is Relation.DISJOINT and rest_multisegment.segments
         or result is Relation.TOUCH or result is Relation.CROSS)
        and relation_with_first_segment is Relation.COMPONENT
        or result is Relation.OVERLAP and
        (relation_with_first_segment is Relation.DISJOINT
         or relation_with_first_segment is Relation.TOUCH
         or relation_with_first_segment is Relation.CROSS)
        or (result is Relation.DISJOINT or result is Relation.TOUCH
            or result is Relation.CROSS)
        and relation_with_first_segment is Relation.OVERLAP,
        next_result is Relation.OVERLAP)
    assert implication(
        next_result is Relation.COMPOSITE,
        (not rest_multisegment.segments or result is Relation.COMPOSITE)
        and relation_with_first_segment is Relation.COMPOSITE)
    assert implication(
        not rest_multisegment.segments
        and relation_with_first_segment is Relation.COMPOSITE,
        next_result is Relation.COMPOSITE)
    assert implication(
        next_result is Relation.EQUAL, not rest_multisegment.segments
        and relation_with_first_segment is Relation.EQUAL
        or result is Relation.COMPOSITE
        and relation_with_first_segment is Relation.COMPOSITE)
    assert implication(
        not rest_multisegment.segments
        and relation_with_first_segment is Relation.EQUAL,
        next_result is Relation.EQUAL)
    assert implication(
        next_result is Relation.COMPONENT, result is Relation.COMPONENT
        or relation_with_first_segment is Relation.COMPONENT
        or result is Relation.OVERLAP and
        (relation_with_first_segment is Relation.COMPOSITE
         or relation_with_first_segment is Relation.OVERLAP)
        or relation_with_first_segment is Relation.COMPONENT)