Repository: Qiskit/qiskit

Issue:
Reading QASM strings with Ion-Trap Gates broken
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: 0.11.0
- **Python version**: 3.7.5
- **Operating system**: Windows

### What is the current behavior?

Cannot construct a quantum Circuit object for non-superconducting gates, even though ion trap gates (RXX, MS, etc) are somewhat supported.

### Steps to reproduce the problem

```python
>>> from qiskit import QuantumCircuit
>>> qc = QuantumCircuit(3)
>>> qc.rxx(3.14, 0, 2)
<qiskit.circuit.instructionset.InstructionSet object at 0x0000018552A839C8>
>>> qc.from_qasm_str(qc.qasm())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[...]\site-packages\qiskit\circuit\quantumcircuit.py", line 1174, in from_qasm_str
    return _circuit_from_qasm(qasm)
  File "[...]\site-packages\qiskit\circuit\quantumcircuit.py", line 1241, in _circuit_from_qasm
    ast = qasm.parse()
  File "[...]\site-packages\qiskit\qasm\qasm.py", line 69, in parse
    return qasm_p.parse(self._data)
  File "[...]\site-packages\qiskit\qasm\qasmparser.py", line 1089, in parse
    self.parser.parse(data, lexer=self.lexer, debug=self.parse_deb)
  File "[...]\site-packages\ply\yacc.py", line 333, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "[...]\site-packages\ply\yacc.py", line 1120, in parseopt_notrack
    p.callable(pslice)
  File "[...]\site-packages\qiskit\qasm\qasmparser.py", line 660, in p_unitary_op_4
    self.verify_as_gate(program[1], program[5], arglist=program[3])
  File "[...]\site-packages\qiskit\qasm\qasmparser.py", line 133, in verify_as_gate
    + "', line", str(obj.line), 'file', obj.file)
qiskit.qasm.exceptions.QasmError: "Cannot find gate definition for 'rxx', line 4 file "
>>> QuantumCircuit.from_qasm_str(qc.qasm())
[SAME ERROR MESSAGE]
```

### What is the expected behavior?

Qiskit should be able to generate a ``QuantumCircuit`` object from a QASM string which includes extension gates.

### Suggested solutions

It appears that the QASM parser needs to be aware of the non-IBM/superconducting gates. Confirm? So a new "iontrap.inc" file (or similar) needs to be created and placed in a path that the QASM parser can recognize? Is there any documentation on writing a new include file?


Discussion:
Can I have a go at it? 

I am new to this, so please correct me if I am wrong at any point. I believe we would need to add the rxx gate (and any other gates defined in qiskit/extensions for full support) in qelib1.inc

Resolving patch:
diff --git a/qiskit/converters/ast_to_dag.py b/qiskit/converters/ast_to_dag.py
--- a/qiskit/converters/ast_to_dag.py
+++ b/qiskit/converters/ast_to_dag.py
@@ -48,8 +48,11 @@
 from qiskit.extensions.standard.rz import RZGate
 from qiskit.extensions.standard.cu1 import Cu1Gate
 from qiskit.extensions.standard.ch import CHGate
+from qiskit.extensions.standard.crx import CrxGate
+from qiskit.extensions.standard.cry import CryGate
 from qiskit.extensions.standard.crz import CrzGate
 from qiskit.extensions.standard.cu3 import Cu3Gate
+from qiskit.extensions.standard.rxx import RXXGate
 from qiskit.extensions.standard.rzz import RZZGate
 
 
@@ -106,6 +109,7 @@ class AstInterpreter:
                           "sdg": SdgGate,
                           "swap": SwapGate,
                           "rx": RXGate,
+                          "rxx": RXXGate,
                           "ry": RYGate,
                           "rz": RZGate,
                           "rzz": RZZGate,
@@ -115,6 +119,8 @@ class AstInterpreter:
                           "cy": CyGate,
                           "cz": CzGate,
                           "ch": CHGate,
+                          "crx": CrxGate,
+                          "cry": CryGate,
                           "crz": CrzGate,
                           "cu1": Cu1Gate,
                           "cu3": Cu3Gate,


Test patch:
diff --git a/test/python/test_qasm_parser.py b/test/python/test_qasm_parser.py
--- a/test/python/test_qasm_parser.py
+++ b/test/python/test_qasm_parser.py
@@ -47,10 +47,10 @@ def test_parser(self):
         res = parse(self.qasm_file_path)
         self.log.info(res)
         # TODO: For now only some basic checks.
-        self.assertEqual(len(res), 1589)
+        self.assertEqual(len(res), 1931)
         self.assertEqual(res[:12], "OPENQASM 2.0")
         self.assertEqual(res[14:41], "gate u3(theta,phi,lambda) q")
-        self.assertEqual(res[1573:1588], "measure r -> d;")
+        self.assertEqual(res[1915:1930], "measure r -> d;")
 
     def test_parser_fail(self):
         """should fail a for a  not valid circuit."""