def tensor(self, *others): if len(others) != 1: return monoidal.Diagram.tensor(self, *others) other, = others f = rigid.Box('f', Ty('c00', 'q00', 'q00'), Ty('c10', 'q10', 'q10')) g = rigid.Box('g', Ty('c01', 'q01', 'q01'), Ty('c11', 'q11', 'q11')) above = Diagram.id(f.dom[:1] @ g.dom[:1] @ f.dom[1:2])\ @ Diagram.swap(g.dom[1:2], f.dom[2:]) @ Diagram.id(g.dom[2:])\ >> Diagram.id(f.dom[:1]) @ Diagram.swap(g.dom[:1], f.dom[1:])\ @ Diagram.id(g.dom[1:]) below =\ Diagram.id(f.cod[:1]) @ Diagram.swap(f.cod[1:], g.cod[:1])\ @ Diagram.id(g.cod[1:])\ >> Diagram.id(f.cod[:1] @ g.cod[:1] @ f.cod[1:2])\ @ Diagram.swap(f.cod[2:], g.cod[1:2]) @ Diagram.id(g.cod[2:]) diagram2tensor = tensor.Functor(ob={ Ty("{}{}{}".format(a, b, c)): z.__getattribute__(y).__getattribute__(x) for a, x in zip(['c', 'q'], ['classical', 'quantum']) for b, y in zip([0, 1], ['dom', 'cod']) for c, z in zip([0, 1], [self, other]) }, ar={ f: self.utensor.array, g: other.utensor.array }) return CQMap(self.dom @ other.dom, self.cod @ other.cod, utensor=diagram2tensor(above >> f @ g >> below))
def downgrade(self): """ Downgrade hypergraph diagram to :class:`discopy.rigid.Diagram`. Examples -------- >>> x = Ty('x') >>> v = Box('v', Ty(), x @ x) >>> print((v >> Swap(x, x) >> v[::-1]).downgrade()) v >> Swap(x, x) >> v[::-1] >>> print((Id(x) @ Swap(x, x) >> v[::-1] @ Id(x)).downgrade()) Id(x) @ Swap(x, x) >> v[::-1] @ Id(x) """ diagram = self.make_progressive() graph = Graph() graph.add_nodes_from(diagram.ports) graph.add_edges_from([(diagram.ports[i], diagram.ports[j]) for i, j in enumerate(diagram.bijection)]) graph.add_nodes_from([ Node("box", depth=depth, box=box if isinstance(box, rigid.Box) else rigid.Box( box.name, box.dom, box.cod, _dagger=box.is_dagger, data=box.data)) for depth, box in enumerate(diagram.boxes) ]) graph.add_nodes_from([ Node("box", depth=len(diagram.boxes) + i, box=rigid.Spider(0, 0, diagram.spider_types[s])) for i, s in enumerate(diagram.scalar_spiders) ]) return drawing.nx2diagram(graph, rigid.Ty, rigid.Id)
def tensor(self, *others): if len(others) != 1: return monoidal.Diagram.tensor(self, *others) f = rigid.Box('f', Ty('c00', 'q00', 'q00'), Ty('c10', 'q10', 'q10')) g = rigid.Box('g', Ty('c01', 'q01', 'q01'), Ty('c11', 'q11', 'q11')) ob = {Ty("{}{}{}".format(a, b, c)): z.__getattribute__(y).__getattribute__(x) for a, x in zip(['c', 'q'], ['classical', 'quantum']) for b, y in zip([0, 1], ['dom', 'cod']) for c, z in zip([0, 1], [self, others[0]])} ar = {f: self.array, g: others[0].array} permute_above = Diagram.id(f.dom[:1] @ g.dom[:1] @ f.dom[1:2])\ @ Diagram.swap(g.dom[1:2], f.dom[2:]) @ Diagram.id(g.dom[2:])\ >> Diagram.id(f.dom[:1]) @ Diagram.swap(g.dom[:1], f.dom[1:])\ @ Diagram.id(g.dom[1:]) permute_below =\ Diagram.id(f.cod[:1]) @ Diagram.swap(f.cod[1:], g.cod[:1])\ @ Diagram.id(g.cod[1:])\ >> Diagram.id(f.cod[:1] @ g.cod[:1] @ f.cod[1:2])\ @ Diagram.swap(f.cod[2:], g.cod[1:2]) @ Diagram.id(g.cod[2:]) F = TensorFunctor(ob, ar) array = F(permute_above >> f @ g >> permute_below).array dom, cod = self.dom @ others[0].dom, self.cod @ others[0].cod return CQMap(dom, cod, array)
return self.ob_factory.tensor( *[self(diagram[i:i + 1]) for i in range(len(diagram))]) if isinstance(diagram, Curry): n_wires = len( self(getattr(diagram.cod, 'left' if diagram.left else 'right'))) return self.ar_factory.curry(self(diagram.diagram), n_wires, diagram.left) for cls, method in [(FA, 'fa'), (BA, 'ba')]: if isinstance(diagram, cls): return getattr(self.ar_factory, method)(self(diagram.dom[:1]), self(diagram.dom[1:])) for cls, method in [(FC, 'fc')]: if isinstance(diagram, cls): left, right = diagram.dom[:1].left, diagram.dom[1:].right middle = diagram.dom[:1].right return getattr(self.ar_factory, method)(self(left), self(middle), self(right)) return super().__call__(diagram) biclosed2rigid_ob = Functor(ob=lambda x: rigid.Ty(x[0].name), ar={}, ob_factory=rigid.Ty) biclosed2rigid = Functor(ob=biclosed2rigid_ob, ar=lambda f: rigid.Box(f.name, biclosed2rigid_ob( f.dom), biclosed2rigid_ob(f.cod)), ob_factory=rigid.Ty, ar_factory=rigid.Diagram)