def intersects(
        self, other: Domain, require_satisfies_left=False, require_satisfies_right=False
    ):
        """Return True if self and other could have a non-empty intersection.

        Parameters
        ----------
        self: Domain - the domain to check
        other: Domain - the domain to check against

        require_satisfies_left: bool -
            If True, assume that `self` is exhaustively specified (ie, any predicates not listed are false),
            and therefore `other` must imply `self` for the intersection to be non-empty.
        require_satisfies_right: bool -
            If True, assume that `other` is exhaustively specified (ie, any predicates not listed are false),
            and therefore `self` must imply `other` for the intersection to be non-empty.
        """

        lazydebug(logger, lambda: f"Domain.intersects for \n\t{self} \n\t{other}")

        if t.contradiction(self.tags.union(other.tags)):
            lazydebug(logger, lambda: f"tag contradiction {self.tags}, {other.tags}")
            return False

        # no relations can contradict eachother
        for ard, brd in itertools.product(self.relations, other.relations):
            if ard is brd:
                continue
            if not reldom_compatible(ard, brd):
                lazydebug(logger, lambda: f"found incompatible {ard} {brd}")
                return False

        # any relations actually known to be present must intersect
        a_pos = [
            rd for rd in self.relations if not isinstance(rd[0], cl.NegatedRelation)
        ]
        b_pos = [
            rd for rd in other.relations if not isinstance(rd[0], cl.NegatedRelation)
        ]
        if require_satisfies_left:
            if not t.satisfies(other.tags, self.tags):
                return False
            for ard in a_pos:
                if not any(reldom_intersects(ard, brd) for brd in b_pos):
                    lazydebug(
                        logger,
                        lambda: f"require_satisfies_left found no intersecting {ard} {b_pos}",
                    )
                    return False
        if require_satisfies_right:
            if not t.satisfies(self.tags, other.tags):
                return False
            for brd in b_pos:
                if not any(reldom_intersects(ard, brd) for ard in a_pos):
                    lazydebug(
                        logger,
                        lambda: f"require_satisfies_right found no intersecting {brd} {a_pos}",
                    )
                    return False

        lazydebug(
            logger, lambda: f"Domain.intersects for {self} {other} returning True"
        )

        return True
Return True if self and other could have a non-empty intersection.

        Parameters
        ----------
        self: Domain - the domain to check
        other: Domain - the domain to check against

        require_satisfies_left: bool -
            If True, assume that `self` is exhaustively specified (ie, any predicates not listed are false),
            and therefore `other` must imply `self` for the intersection to be non-empty.
        require_satisfies_right: bool -
            If True, assume that `other` is exhaustively specified (ie, any predicates not listed are false),
            and therefore `self` must imply `other` for the intersection to be non-empty.
        
infinigen/core/constraints/reasoning/domain.py