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

Rewrite rule for removing redundant swaps #57

Open
kinianlo opened this issue Feb 24, 2022 · 9 comments
Open

Rewrite rule for removing redundant swaps #57

kinianlo opened this issue Feb 24, 2022 · 9 comments

Comments

@kinianlo
Copy link
Contributor

I am wondering if discopy has any rewriting tools for removing redundant swaps? Specifically, I am trying to automatically remove this kind of redundant swaps:
download

which is, I believe, equivalent to the followings up to symmetries:
download
download
download

@toumix
Copy link
Collaborator

toumix commented Feb 25, 2022

You can translate your diagram back and forth the hypergraph.Diagram class:

from discopy import Ty, Id, Swap, hypergraph
x = Ty("x")
back_n_forth = lambda f: hypergraph.Diagram.upgrade(f).downgrade()
assert back_n_forth(Swap(x, x) >> Swap(x, x)) == Id(x @ x)

The only price to pay is that hypergraph categories are self-adjoint so this will remove all the adjoints from your diagram (i.e. x.r and x.l are both mapped to x).

@y-richie-y
Copy link
Collaborator

What if we wrapped all the types? @toumix

@JosephNathaniel
Copy link

Hi there, I tried using the back_n_forth function above to simplify redundant swaps, but in some cases it doesn't appear to have the desired behaviour. For instance, consider the diagram

Diagram(dom=Ty(), cod=Ty('n', 'n'), boxes=[Box('Alice', Ty(), Ty('n')), Box('Bob', Ty(), Ty('n')), Box('hates', Ty('n', 'n'), Ty('n', 'n'))], offsets=[0, 1, 0])
image

Applying back_n_forth yields
image

@toumix
Copy link
Collaborator

toumix commented Aug 9, 2022

The problem comes from the greedy algorithm used for the "forth" part of back_n_forth: it takes the boxes one at a time and when they have no wires coming in, it plugs them on the left of the diagram. This is the reason the unnecessary swap is introduced in your example.

I don't think there is an obvious way to solve this problem. Planarity testing for graphs is a non-trivial problem, it can be solved in linear time but this requires some clever data structures. Adapting those data structures to diagrams, represented as graphs with extra structure, sounds like a very cool project but maybe it's a bit too much effort for the expected payoff.

@toumix
Copy link
Collaborator

toumix commented Aug 9, 2022

Maybe the diagrams you are trying to simplify have some special shape for which a simple heuristic can do the trick? In your example it would make sense to add the new boxes to the right hand side instead, this would be very easy to implement.

@RazinShaikh
Copy link
Collaborator

Can you share a code snippet for adding new boxes to the right instead?

@toumix
Copy link
Collaborator

toumix commented Aug 9, 2022

I'm busy with other things right now but you can try replacing this one line: https://github.com/oxford-quantum-group/discopy/blob/87dcd350480532b616eb7acf9043ab94b8300c70/discopy/drawing.py#L223

with

box, offset = box_node.box, getattr(box_node, "offset", len(scan))

@toumix
Copy link
Collaborator

toumix commented Aug 9, 2022

Even better, you could submit a PR for a new optional argument to hypergraph.Diagram.downgrade for switching from left to right.

@RazinShaikh
Copy link
Collaborator

Thanks, I will look into it

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

5 participants