Exemplo n.º 1
0
    def tensor(self, *others):
        """
        Returns the horizontal composition of 'self' with a diagram 'other'.

        This method is called using the binary operator `@`:

        >>> x, y, z, w = Ty('x'), Ty('y'), Ty('z'), Ty('w')
        >>> f0, f1 = Box('f0', x, y), Box('f1', z, w)
        >>> assert f0 @ f1 == f0.tensor(f1) == f0 @ Id(z) >> Id(y) @ f1

        Parameters
        ----------
        other : :class:`Diagram`

        Returns
        -------
        diagram : :class:`Diagram`
            the tensor of 'self' and 'other'.
        """
        if not others:
            return self
        if len(others) > 1:
            return self.tensor(others[0]).tensor(*others[1:])
        other = others[0]
        if not isinstance(other, Diagram):
            raise TypeError(messages.type_err(Diagram, other))
        dom, cod = self.dom @ other.dom, self.cod @ other.cod
        boxes = self.boxes + other.boxes
        offsets = self.offsets + [n + len(self.cod) for n in other.offsets]
        layers = cat.Id(dom)
        for left, box, right in self.layers:
            layers = layers >> Layer(left, box, right @ other.dom)
        for left, box, right in other.layers:
            layers = layers >> Layer(self.cod @ left, box, right)
        return Diagram(dom, cod, boxes, offsets, layers=layers)
Exemplo n.º 2
0
 def __init__(self, dom, cod, boxes, offsets, layers=None):
     if not isinstance(dom, Ty):
         raise TypeError(messages.type_err(Ty, dom))
     if not isinstance(cod, Ty):
         raise TypeError(messages.type_err(Ty, cod))
     if len(boxes) != len(offsets):
         raise ValueError(messages.boxes_and_offsets_must_have_same_len())
     if layers is None:
         layers = cat.Id(dom)
         for box, off in zip(boxes, offsets):
             if not isinstance(box, Diagram):
                 raise TypeError(messages.type_err(Diagram, box))
             if not isinstance(off, int):
                 raise TypeError(messages.type_err(int, off))
             left = layers.cod[:off] if layers else dom[:off]
             right = layers.cod[off + len(box.dom):]\
                 if layers else dom[off + len(box.dom):]
             layers = layers >> Layer(left, box, right)
         layers = layers >> cat.Id(cod)
     self._layers, self._offsets = layers, tuple(offsets)
     super().__init__(dom, cod, boxes, _scan=False)
Exemplo n.º 3
0
    def tensor(self, other=None, *rest):
        """
        Returns the horizontal composition of 'self' with a diagram 'other'.

        This method is called using the binary operator `@`:

        >>> x, y, z, w = Ty('x'), Ty('y'), Ty('z'), Ty('w')
        >>> f0, f1 = Box('f0', x, y), Box('f1', z, w)
        >>> assert f0 @ f1 == f0.tensor(f1) == f0 @ Id(z) >> Id(y) @ f1

        >>> (f0 @ f1).draw(
        ...     figsize=(2, 2),
        ...     path='docs/_static/imgs/monoidal/tensor-example.png')

        .. image:: ../_static/imgs/monoidal/tensor-example.png
            :align: center

        Parameters
        ----------
        other : :class:`Diagram`

        Returns
        -------
        diagram : :class:`Diagram`
            the tensor of 'self' and 'other'.
        """
        if other is None:
            return self
        if rest:
            return self.tensor(other).tensor(*rest)
        if isinstance(other, Sum):
            return self.sum([self]).tensor(other)
        if not isinstance(other, Diagram):
            raise TypeError(messages.type_err(Diagram, other))
        dom, cod = self.dom @ other.dom, self.cod @ other.cod
        boxes = self.boxes + other.boxes
        offsets = self.offsets + [n + len(self.cod) for n in other.offsets]
        layers = cat.Id(dom)
        for left, box, right in self.layers:
            layers = layers >> Layer(left, box, right @ other.dom)
        for left, box, right in other.layers:
            layers = layers >> Layer(self.cod @ left, box, right)
        return self.upgrade(Diagram(dom, cod, boxes, offsets, layers=layers))
Exemplo n.º 4
0
 def __init__(self, dom):
     monoidal.Id.__init__(self, dom)
     Diagram.__init__(self, dom, dom, [], [], layers=cat.Id(dom))
Exemplo n.º 5
0
 def __init__(self, t):
     super().__init__(t, t, [], [], layers=cat.Id(t))
Exemplo n.º 6
0
 def __init__(self, dom=Dim()):
     rigid.Id.__init__(self, dom)
     Diagram.__init__(self, dom, dom, [], [], layers=cat.Id(dom))
Exemplo n.º 7
0
 def __init__(self, dom=Ty()):
     cat.Id.__init__(self, dom)
     Diagram.__init__(self, dom, dom, [], [], layers=cat.Id(dom))
Exemplo n.º 8
0
 def __init__(self, x):
     super().__init__(x, x, [], [], layers=cat.Id(x))
Exemplo n.º 9
0
 def __str__(self):
     return ("{} @ ".format(cat.Id(self._left)) if self._left else "")\
         + str(self._box)\
         + (" @ {}".format(cat.Id(self._right)) if self._right else "")