diff --git a/pytket/tests/clexpr_test.py b/pytket/tests/clexpr_test.py index e078224aa0..a585961cf4 100644 --- a/pytket/tests/clexpr_test.py +++ b/pytket/tests/clexpr_test.py @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json +from jsonschema import validate # type: ignore +from pathlib import Path from pytket.circuit import ( Bit, CircBox, @@ -21,11 +24,15 @@ ClExprOp, ClOp, ClRegVar, - OpType, WiredClExpr, ) from pytket.qasm import circuit_to_qasm_str, circuit_from_qasm_str +with open( + Path(__file__).resolve().parent.parent.parent / "schemas/circuit_v1.json", "r" +) as f: + SCHEMA = json.load(f) + def test_op() -> None: reg_add = ClOp.RegAdd @@ -114,16 +121,25 @@ def test_wexpr() -> None: def test_adding_to_circuit() -> None: - expr = ClExpr(op=ClOp.BitXor, args=[ClBitVar(0), ClBitVar(1)]) - wexpr = WiredClExpr(expr=expr, bit_posn={0: 0, 1: 1}, output_posn=[2]) + expr0 = ClExpr(op=ClOp.BitXor, args=[ClBitVar(0), ClBitVar(1)]) + wexpr0 = WiredClExpr(expr=expr0, bit_posn={0: 0, 1: 1}, output_posn=[2]) + expr1 = ClExpr( + op=ClOp.RegDiv, + args=[ClRegVar(0), ClExpr(op=ClOp.RegAdd, args=[2, ClBitVar(0)])], + ) + wexpr1 = WiredClExpr( + expr=expr1, bit_posn={0: 1}, reg_posn={0: [2, 0]}, output_posn=[2, 0] + ) c = Circuit(0, 3) - c.add_clexpr(wexpr, c.bits) + c.add_clexpr(wexpr0, c.bits) + c.add_clexpr(wexpr1, c.bits) cmds = c.get_commands() - assert len(cmds) == 1 + assert len(cmds) == 2 op = cmds[0].op assert isinstance(op, ClExprOp) - assert op.expr == wexpr + assert op.expr == wexpr0 d = c.to_dict() + validate(instance=d, schema=SCHEMA) c1 = Circuit.from_dict(d) assert c == c1 d1 = c1.to_dict() diff --git a/schemas/circuit_v1.json b/schemas/circuit_v1.json index c801393fbd..d788e573d3 100644 --- a/schemas/circuit_v1.json +++ b/schemas/circuit_v1.json @@ -302,6 +302,9 @@ }, "classical": { "$ref": "#/definitions/classical" + }, + "expr": { + "$ref": "#/definitions/wiredclexpr" } }, "required": [ @@ -357,6 +360,20 @@ "classical" ] } + }, + { + "if": { + "properties": { + "type": { + "const": "ClExpr" + } + } + }, + "then": { + "required": [ + "expr" + ] + } } ] }, @@ -1178,6 +1195,147 @@ "qubits" ], "additionalProperties": false + }, + "wiredclexpr": { + "type": "object", + "description": "A classical operation defined over a sequence of bits.", + "properties": { + "expr": { + "$ref": "#/definitions/clexpr" + }, + "bit_posn": { + "type": "array", + "description": "List of pairs representing map from bit-variable indices to wire positions.", + "items": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "reg_posn": { + "type": "array", + "description": "List of pairs representing map from register-variable indices to lists of wire positions.", + "items": { + "type": "array", + "items": [ + { + "type": "integer" + }, + { + "type": "array", + "items": { + "type": "integer" + } + } + ] + } + }, + "output_posn": { + "type": "array", + "description": "List of wire positions of output bits.", + "items": { + "type": "integer" + } + } + }, + "required": [ + "expr", + "bit_posn", + "reg_posn", + "output_posn" + ], + "additionalProperties": false + }, + "clexpr": { + "type": "object", + "description": "An abstract classical expression.", + "properties": { + "op": { + "description": "The operation type.", + "type": "string" + }, + "args": { + "type": "array", + "description": "List of arguments to the operation.", + "items": { + "$ref": "#/definitions/clexprarg" + } + } + } + }, + "clexprarg":{ + "type": "object", + "description": "Argument to a classical expression.", + "properties": { + "type": { + "description": "The type of argument.", + "type": "string", + "enum": [ + "term", + "expr" + ] + }, + "input": { + "anyOf": [ + { + "$ref": "#/definitions/clexprterm" + }, + { + "$ref": "#/definitions/clexpr" + } + ] + } + } + }, + "clexprterm": { + "type": "object", + "description": "A term in a classical expression.", + "properties": { + "type": { + "description": "The type of term.", + "type": "string", + "enum": [ + "int", + "var" + ] + }, + "term": { + "anyOf": [ + { + "type": "integer" + }, + { + "$ref": "#/definitions/clvar" + } + ] + } + } + }, + "clvar": { + "type": "object", + "description": "A free variable in a classical expression.", + "properties": { + "type": { + "description": "The type of variable.", + "type": "string", + "enum": [ + "bit", + "ref" + ] + }, + "var": { + "$ref": "#/definitions/clindex" + } + } + }, + "clindex": { + "type": "object", + "properties": { + "index": { + "type": "integer" + } + } } } }