Composing graphs loses grounds?
Closed this issue · 1 comments
semiclassical commented
To represent a one-qubit Z-measurement, I create a green phaseless spider with one input / one output and set it as a ground. At first glance, PyZX can handle this just fine:
c=zx.Circuit(1)
c.add_gate("ZPhase",0,phase=0)
g=c.to_graph()
g.set_ground(1)
zx.draw(g)
![measurement](https://private-user-images.githubusercontent.com/63672881/280485157-281c1d1b-d4fe-48ae-89a6-3b9bb38996bd.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2MTAwODcsIm5iZiI6MTcxOTYwOTc4NywicGF0aCI6Ii82MzY3Mjg4MS8yODA0ODUxNTctMjgxYzFkMWItZDRmZS00OGFlLTg5YTYtM2I5YmIzODk5NmJkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDIxMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWZjNTVlZTg4ZGJlYjMwZjU1ZWM5YjdhNTJiNDM4NGJhZTk0MGNmMzZmNDYzZjM1ZWY1ZDE1YjQ4MDA4NDExMWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.7RruUAkxD3Moc2VimfNqn0OkkxyAuEi4rbQ9516Nlec)
However, if I compose this graph with itself (zx.draw(g*g
) then the second spider is no longer a ground:
![measurement2](https://private-user-images.githubusercontent.com/63672881/280485159-304b4275-7d9a-4f2e-bf93-e254b57c7f0a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2MTAwODcsIm5iZiI6MTcxOTYwOTc4NywicGF0aCI6Ii82MzY3Mjg4MS8yODA0ODUxNTktMzA0YjQyNzUtN2Q5YS00ZjJlLWJmOTMtZTI1NGI1N2M3ZjBhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDIxMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWRjMTMxMGIzZTVmNTk3NDllYzI4MDE3ODYxYTg4ZmJjOTk2YWRhMDRjZDA2ZDQ5NzY1M2ZiZmZiYzdjMDFmMDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.PCVM2qifNHMDNaxkmvJo5foJsXe8Lurb_gxkwm8b3is)
I've verified this as well for larger examples where the two graphs are different:
q=5;
c1=zx.Circuit(q)
for i in range(0,q-1,2):
c1.add_gate("CNOT",i,i+1)
g1=c1.to_graph()
g1.auto_detect_io()
g2=zx.generate.identity(q)
for i in range(q):
g2.set_type(2*i+1,1)
g2.set_ground(2*i+1)
v = g2.add_vertex(qubit=i,row=2)
g2.add_edge(g2.edge(v,2*i+1),edgetype=zx.EdgeType.SIMPLE)
g2.auto_detect_io()
![bad grounds](https://private-user-images.githubusercontent.com/63672881/280485658-0da43ce4-d0d4-405b-a4f6-672b6aba08c8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2MTAwODcsIm5iZiI6MTcxOTYwOTc4NywicGF0aCI6Ii82MzY3Mjg4MS8yODA0ODU2NTgtMGRhNDNjZTQtZDBkNC00MDViLWE0ZjYtNjcyYjZhYmEwOGM4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDIxMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTg2ZDM4ZjRiNmM2MTU4N2Q2OTQ1MzI1ZGY1MmYzZmRhYjg5OTMyYzM3ZjBmYzYzNDNhN2M2MGY1NWFlMjBiZTImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.CApYYTDUaIl55GfkvgB4E8r3b9TKheuyjjVSo_mn-yI)