Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tensor product of pregroup diagrams #56

Open
kinianlo opened this issue Feb 24, 2022 · 1 comment
Open

Tensor product of pregroup diagrams #56

kinianlo opened this issue Feb 24, 2022 · 1 comment

Comments

@kinianlo
Copy link
Contributor

Currently, in version 0.3.7.2, the tensor product of two pregroup diagrams is not a pregroup diagram. (pregroup diagrams are those with all the words at the top). This behaviour is evident when trying to draw the tensored diagram with discopy.grammar.draw.

Example

from discopy import Word, Cup, Id
from discopy.grammar import draw 

n, s = Ty('n'), Ty('s')
john = Word('John', n)
talks = Word('talks', n.r @ s)
walks = Word('walks', n.r @ s)

sent1 = john @ talks >> Cup(n, n.r) @ Id(S)
sent2 = john @ walks >> Cup(n, n.r) @ Id(S)

draw(sent1 @ sent2)

ouptut:

ValueError: Expected a pregroup diagram of shape`word @ ... @ word >> cups_and_swaps`, use diagram.draw() instead.

The reason is that the method discopy.rigid.Diagram.tensor puts the boxes of sent2 after all the boxes of sent1, so that the word boxes of sent2 will appear after the cups in sent1.

If I am not mistaken, there is currently no function in discopy that would tensor together two pregroup diagrams while making sure the output is also a pregroup diagram.

I'd suggest adding a function discopy.grammar.tensor that have the required behaviour.

@toumix
Copy link
Collaborator

toumix commented Feb 25, 2022

It's true we never had to take the tensor of two pregroup diagrams. What is your use case exactly?

When you have two diagrams f0 >> g0 and f1 >> g1 with f1.dom == x1 and g0.cod = y0, DisCoPy defines their tensor (f0 >> g0) @ (f1 >> g1) as first all of the left-hand side then all of the right hand-side.

In this case what you want is f0 @ f1 >> g0 @ g1, so you could do something like:

def words_and_cups(self):
    i = max(i for i, box in enumerate(self.boxes) if isinstance(box, Word))
    return self[:i], self[i:]

def tensor(self, other):
    f0, g0 = words_and_cups(self)
    f1, g1 = words_and_cups(other)
    return f0 @ f1 >> g0 @ g1

Right now there isn't a dedicated pregroup.Diagram class, they're just a special case of rigid.Diagram so we can't change the way tensor is defined. That's also why we have to do pregroup.draw(diagram) rather than just diagram.draw().

It would be a good idea to implement such a class, I'll make sure to add it to the v1.0 features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants