From d5b6d249c8b649f7bd1132aeac7f700d58f3b052 Mon Sep 17 00:00:00 2001 From: Ori Roth Date: Mon, 28 Apr 2025 12:44:31 +0300 Subject: [PATCH 1/2] Remove generative=True --- algorithms/algebraic/shor/shor.ipynb | 16 +++++---- .../solving_qlsp/solving_qlsp_with_aqc.ipynb | 6 ++-- algorithms/dqi/dqi_max_xorsat.ipynb | 36 +++++++++---------- .../quantum_thermal_state_preparation.ipynb | 2 +- .../qsvm_pauli_feature_map.ipynb | 16 ++++----- .../cooling_systems_optimization.ipynb | 36 +++++-------------- .../credit_card_fraud/credit_card_fraud.ipynb | 9 +++-- ...ssion_algorithm_for_symmetric_states.ipynb | 30 ++++++++-------- .../classical_variables_and_operations.ipynb | 22 ++++++------ 9 files changed, 76 insertions(+), 97 deletions(-) diff --git a/algorithms/algebraic/shor/shor.ipynb b/algorithms/algebraic/shor/shor.ipynb index cbef63a9b..e149f36bc 100644 --- a/algorithms/algebraic/shor/shor.ipynb +++ b/algorithms/algebraic/shor/shor.ipynb @@ -199,7 +199,7 @@ " )\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def phase_lad(\n", " value: int,\n", " phi_b: QArray[QBit],\n", @@ -220,8 +220,8 @@ "\n", "@qfunc\n", "def ccmod_add(\n", - " N: CInt,\n", - " a: CInt,\n", + " N: int,\n", + " a: int,\n", " phi_b: QArray[QBit], # b in fourier basis\n", " c1: QBit,\n", " c2: QBit,\n", @@ -405,7 +405,7 @@ }, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def cmod_mult(\n", " N: int,\n", " a: int,\n", @@ -466,8 +466,10 @@ }, "outputs": [], "source": [ + "from sympy import mod_inverse\n", + "\n", "from classiq.qmod import SWAP, free\n", - "from classiq.qmod.symbolic import min, mod_inverse\n", + "from classiq.qmod.symbolic import min\n", "\n", "\n", "@qfunc\n", @@ -478,7 +480,7 @@ " )\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def cmod_mult_pair(\n", " N: int,\n", " a: int,\n", @@ -529,7 +531,7 @@ }, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def mod_exp_func(\n", " N: int,\n", " a: int,\n", diff --git a/algorithms/aqc/solving_qlsp/solving_qlsp_with_aqc.ipynb b/algorithms/aqc/solving_qlsp/solving_qlsp_with_aqc.ipynb index af5cf8de2..975909801 100644 --- a/algorithms/aqc/solving_qlsp/solving_qlsp_with_aqc.ipynb +++ b/algorithms/aqc/solving_qlsp/solving_qlsp_with_aqc.ipynb @@ -578,12 +578,12 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def adiabatic_evolution_qfunc(\n", " H0: CArray[PauliTerm],\n", " H1: CArray[PauliTerm],\n", - " evolution_time: CInt,\n", - " num_steps: CInt,\n", + " evolution_time: int,\n", + " num_steps: int,\n", " qba: QArray[QBit],\n", "):\n", " # Time step for each increment\n", diff --git a/algorithms/dqi/dqi_max_xorsat.ipynb b/algorithms/dqi/dqi_max_xorsat.ipynb index 41e23cfd3..bbfc4aba1 100644 --- a/algorithms/dqi/dqi_max_xorsat.ipynb +++ b/algorithms/dqi/dqi_max_xorsat.ipynb @@ -168,7 +168,7 @@ " inplace_binary_to_one_hot(one_hot)\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def inplace_binary_to_one_hot(one_hot: QArray):\n", " temp_qvars = [QBit(f\"temp_{i}\") for i in range(one_hot.len)]\n", " bind(one_hot, temp_qvars)\n", @@ -283,8 +283,8 @@ "from classiq.qmod.symbolic import acos, min as qmin, sqrt\n", "\n", "\n", - "@qfunc(generative=True)\n", - "def _dicke_split_cycle_shift(k: CInt, qvar: QArray[QBit]):\n", + "@qfunc\n", + "def _dicke_split_cycle_shift(k: int, qvar: QArray[QBit]):\n", " \"\"\"\n", " internal function, assumes the input is in the form |11..100..0> with up to k ones.\n", " transforms the state to: sqrt(1/n)*|11..100..0> + sqrt((n-1)/n)*|01..110..0>.\n", @@ -305,21 +305,19 @@ " )\n", "\n", "\n", - "@qfunc(generative=True)\n", - "def prepare_dick_state_unary_input(max_k: CInt, qvar: QArray[QBit]):\n", + "@qfunc\n", + "def prepare_dick_state_unary_input(max_k: int, qvar: QArray[QBit]):\n", " \"\"\"\n", " assumes the input is encoded in qvar in unary encoding. should work for every value\n", " smaller than max_k\n", " \"\"\"\n", " if qvar.len > 1:\n", " _dicke_split_cycle_shift(max_k, qvar)\n", - " prepare_dick_state_unary_input(\n", - " qmin(max_k, qvar.len - 2), qvar[1 : qvar.len]\n", - " )\n", + " prepare_dick_state_unary_input(qmin(max_k, qvar.len - 2), qvar[1 : qvar.len])\n", "\n", "\n", "@qfunc\n", - "def prepare_dicke_state(k: CInt, qvar: QArray[QBit]):\n", + "def prepare_dicke_state(k: int, qvar: QArray[QBit]):\n", " apply_to_all(X, qvar[0:k])\n", " prepare_dick_state_unary_input(k, qvar)" ] @@ -412,13 +410,11 @@ " repeat(y.len, lambda i: if_(v[i] > 0, lambda: Z(y[i])))\n", "\n", "\n", - "@qfunc(generative=True)\n", - "def matrix_vector_product(B: CArray[CArray[CInt]], y: QArray, out: Output[QArray]):\n", - " allocate(B.len, out)\n", - " for i in range(B.len):\n", - " out[i] ^= reduce(\n", - " lambda x, y: x ^ y, [int(B[i][j]) * y[j] for j in range(y.len)]\n", - " )" + "@qfunc\n", + "def matrix_vector_product(B: list[list[int]], y: QArray, out: Output[QArray]):\n", + " allocate(len(B), out)\n", + " for i in range(len(B)):\n", + " out[i] ^= reduce(lambda x, y: x ^ y, [int(B[i][j]) * y[j] for j in range(y.len)])" ] }, { @@ -463,11 +459,11 @@ " bind([qvar, extension], qvar_padded)\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def dqi_max_xor_sat(\n", - " B: CArray[CArray[CInt]],\n", - " v: CArray[CInt],\n", - " w_k: CArray[CReal],\n", + " B: list[list[int]],\n", + " v: list[int],\n", + " w_k: list[float],\n", " y: Output[QArray],\n", " solution: Output[QArray],\n", " syndrom_decode: QCallable[QArray, QArray],\n", diff --git a/algorithms/gibbs/quantum_thermal_state_preparation.ipynb b/algorithms/gibbs/quantum_thermal_state_preparation.ipynb index e3de60bb6..3b9430661 100644 --- a/algorithms/gibbs/quantum_thermal_state_preparation.ipynb +++ b/algorithms/gibbs/quantum_thermal_state_preparation.ipynb @@ -248,7 +248,7 @@ " return grid, amplitudes\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def prepare_gaussian_state(t: QArray):\n", " grid, amplitudes = get_gaussian_amplitudes(t.len)\n", " inplace_prepare_amplitudes(amplitudes.tolist(), 0, t)\n", diff --git a/algorithms/qml/qsvm_pauli_feature_map/qsvm_pauli_feature_map.ipynb b/algorithms/qml/qsvm_pauli_feature_map/qsvm_pauli_feature_map.ipynb index c08e1ce36..fa9f3a39e 100644 --- a/algorithms/qml/qsvm_pauli_feature_map/qsvm_pauli_feature_map.ipynb +++ b/algorithms/qml/qsvm_pauli_feature_map/qsvm_pauli_feature_map.ipynb @@ -214,9 +214,9 @@ "\n", "def generate_hamiltonian(\n", " data: CArray[CReal],\n", - " paulis_list: CArray[CArray[Pauli]],\n", - " affines: CArray[CArray[CReal, 2]],\n", - " connectivity: CInt,\n", + " paulis_list: list[list[Pauli]],\n", + " affines: list[list[float]],\n", + " connectivity: int,\n", ") -> CArray[PauliTerm]:\n", " assert connectivity in [\n", " 0,\n", @@ -242,7 +242,7 @@ "id": "45b594cf-76b5-4db8-a64a-9fb8dd30b1c2", "metadata": {}, "source": [ - "Next, we define a quantum function for the Pauli feature map, working in generative mode:" + "Next, we define a quantum function for the Pauli feature map:" ] }, { @@ -252,12 +252,12 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def pauli_kernel(\n", " data: CArray[CReal],\n", - " paulis_list: CArray[CArray[Pauli]],\n", - " affines: CArray[CArray[CReal, 2]],\n", - " connectivity: CInt,\n", + " paulis_list: list[list[Pauli]],\n", + " affines: list[list[float]],\n", + " connectivity: int,\n", " reps: CInt,\n", " qba: QArray[QBit],\n", ") -> None:\n", diff --git a/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb b/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb index 4f8f2687e..f64ad5ef1 100644 --- a/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb +++ b/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb @@ -567,10 +567,7 @@ "end_time": "2025-04-28T13:42:46.892202Z", "start_time": "2025-04-28T13:42:46.890683Z" }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -969,10 +966,7 @@ "cell_type": "markdown", "id": "fbd84d5c", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "We take 5 QPE phase qubits `qpe_phase_size`." @@ -1115,10 +1109,7 @@ "cell_type": "markdown", "id": "724fa21d", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "#### The circuit becomes very big. Thus, we do not synthesize the circuit in this demo-notebook because it takes a lot of time." @@ -1133,10 +1124,7 @@ "end_time": "2025-04-28T13:53:40.043261Z", "start_time": "2025-04-28T13:53:40.041952Z" }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -1290,8 +1278,8 @@ " )\n", "\n", "\n", - "@qfunc(generative=True)\n", - "def dummy_qae(magnitudes_list: CArray[CArray[CReal]], phases_list: CArray[CArray[CReal]], qae_phase: QArray, reg: QNum):\n", + "@qfunc\n", + "def dummy_qae(magnitudes_list: list[list[float]], phases_list: list[list[float]], qae_phase: QArray, reg: QNum):\n", " dummy_data = QBit()\n", " full_qae = QArray()\n", " allocate(1, dummy_data)\n", @@ -1312,7 +1300,7 @@ " dummy_cost_layer(qae_phase, reg, gamma)\n", " mixer_layer(reg, beta)\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def qaoa_circuit(\n", " gammas: CArray[CReal],\n", " betas: CArray[CReal],\n", @@ -1374,10 +1362,7 @@ "cell_type": "markdown", "id": "b7a5550f", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "By using more phase qubits and optimizing on the gamma and betas parameters, you can find the optimal solution with high probability." @@ -1388,10 +1373,7 @@ "execution_count": null, "id": "b5bafd12", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [] diff --git a/applications/finance/credit_card_fraud/credit_card_fraud.ipynb b/applications/finance/credit_card_fraud/credit_card_fraud.ipynb index 1feed8e33..670cb173d 100644 --- a/applications/finance/credit_card_fraud/credit_card_fraud.ipynb +++ b/applications/finance/credit_card_fraud/credit_card_fraud.ipynb @@ -1023,12 +1023,12 @@ " return ham\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def pauli_kernel(\n", " data: CArray[CReal],\n", - " paulis_list: CArray[CArray[Pauli]],\n", - " affines: CArray[CArray[CReal, 2]],\n", - " connectivity: CInt,\n", + " paulis_list: list[list[Pauli]],\n", + " affines: list[list[float]],\n", + " connectivity: int,\n", " reps: CInt,\n", " qba: QArray[QBit],\n", ") -> None:\n", @@ -1113,7 +1113,6 @@ "\n", "@qfunc\n", "def main(data1: CArray[CReal, N_DIM], data2: CArray[CReal, N_DIM], qba: Output[QNum]):\n", - "\n", " allocate(data1.len, qba)\n", " pauli_kernel(data1, PAULIS, AFFINES, CONNECTIVITY, REPS, qba)\n", " invert(lambda: pauli_kernel(data2, PAULIS, AFFINES, CONNECTIVITY, REPS, qba))\n", diff --git a/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb b/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb index 749debeaf..bc3870671 100644 --- a/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb +++ b/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb @@ -230,7 +230,7 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def apply_matrix(matrix: CArray[CArray[CReal]], q1: QBit, q2: QBit, q3: QBit) -> None:\n", " \"\"\"\n", " Apply the gate given by the matrix to three qubits given as parameters.\n", @@ -262,8 +262,8 @@ "from functools import reduce\n", "\n", "\n", - "@qfunc(generative=True)\n", - "def apply_MultiCNOT(q: QArray[QBit], controls: CArray[CInt]):\n", + "@qfunc\n", + "def apply_MultiCNOT(q: QArray[QBit], controls: list[int]):\n", " \"\"\"\n", " Apply a multi-controlled NOT gate to a set of qubits.\n", " Arguments:\n", @@ -274,8 +274,8 @@ "\n", " # constructing a temporary QArray of qubits representing the specific qubits in q given by the indexes in controls\n", " control(\n", - " reduce(lambda x, y: x & y, [q[i] for i in list(controls)[:-1]]),\n", - " lambda: X(q[controls[controls.len - 1]]),\n", + " reduce(lambda x, y: x & y, [q[i] for i in controls[:-1]]),\n", + " lambda: X(q[controls[-1]]),\n", " )" ] }, @@ -295,8 +295,8 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", - "def apply_U_ab(a: CInt, q: QArray[QBit]):\n", + "@qfunc\n", + "def apply_U_ab(a: int, q: QArray[QBit]):\n", " \"\"\"\n", " Arguments:\n", " a: integer value representing the index of qubit a.\n", @@ -324,8 +324,8 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", - "def apply_U_f(a: CInt, q: QArray[QBit]):\n", + "@qfunc\n", + "def apply_U_f(a: int, q: QArray[QBit]):\n", " \"\"\"\n", " Arguments:\n", " a: integer value representing the index of qubit a.\n", @@ -351,7 +351,7 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def apply_U(q: QArray[QBit]):\n", " \"\"\"\n", " Arguments:\n", @@ -384,7 +384,7 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def onehot_to_binary_encode(q: QArray[QBit]) -> None:\n", " \"\"\"\n", " Convert the one-hot encoding of the qubits to binary encoding.\n", @@ -424,7 +424,7 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def symmetric_compression_algorithm(q_array: QArray[QBit]):\n", " \"\"\"\n", " The main function that implements the symmetric compression algorithm as described in the paper.\n", @@ -466,7 +466,7 @@ "metadata": {}, "outputs": [], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def main(x: Output[QArray]):\n", " allocate(5, x)\n", " hadamard_transform(x)\n", @@ -528,7 +528,7 @@ } ], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def main(x: Output[QArray]):\n", " amplitude = [0, 1 / 3, 1 / 3, 0, 1 / 3, 0, 0, 0]\n", " prepare_amplitudes(amplitude, 0, x)\n", @@ -591,7 +591,7 @@ } ], "source": [ - "@qfunc(generative=True)\n", + "@qfunc\n", "def main(x: Output[QArray]):\n", " allocate(3, x)\n", " hadamard_transform(x)\n", diff --git a/tutorials/classiq_101/classiq_concepts/design/classical_variables_and_operations/classical_variables_and_operations.ipynb b/tutorials/classiq_101/classiq_concepts/design/classical_variables_and_operations/classical_variables_and_operations.ipynb index 460ce3ea4..237839b96 100644 --- a/tutorials/classiq_101/classiq_concepts/design/classical_variables_and_operations/classical_variables_and_operations.ipynb +++ b/tutorials/classiq_101/classiq_concepts/design/classical_variables_and_operations/classical_variables_and_operations.ipynb @@ -3,7 +3,9 @@ { "cell_type": "markdown", "metadata": {}, - "source": "# Design - Classical Control Flow" + "source": [ + "# Design - Classical Control Flow" + ] }, { "cell_type": "markdown", @@ -20,23 +22,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Generative Functions in Qmod" + "### Generative Descriptions in Qmod" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Generative functions in Qmod offer a powerful way to create and manipulate classical objects of Qmod with Python constructs. These functions allow the interaction between quantum and classical variables, enabling advanced logic and operations. Currently, it is possible to benefit from the following Python features within quantum programs using generative functions:\n", + "Generative descriptions in Qmod offer a powerful way to create and manipulate classical objects of Qmod with Python constructs. These functions allow the interaction between quantum and classical variables, enabling advanced logic and operations. Currently, it is possible to benefit from the following Python features within quantum programs using generative descriptions:\n", "\n", "- **`range`**: Generate sequences of classical values to iterate quantum operations dynamically over classical types within Qmod types. \n", "- **`if` statements**: Define conditional logic for generating and applying quantum operations using Qmod types as classical control parameters.\n", "- **Treating quantum constants as classical**: Converts parameters intricate to the quantum systems to Python types. This allows one to use, for example, integration of functions from external packages such as `math.sqrt` over classical quantities of a quantum object, such as the `len` of a quantum array.\n", "\n", "\n", - "Generative functions provide an elegant way to manage hybrid classical-quantum workflows, enhancing the expressiveness of your quantum algorithms. For more details and examples, refer to the [Generative Functions documentation](https://docs.classiq.io/latest/qmod-reference/language-reference/generative-functions/?h=ge).\n", - "\n", - "To enable generative functions in quantum function, it is necessary to modify the `@qfunc` decorator to `@qfunc(generative=True)`.\n", + "Generative descriptions provide an elegant way to manage hybrid classical-quantum workflows, enhancing the expressiveness of your quantum algorithms. For more details and examples, refer to the [Generative Descriptions documentation](https://docs.classiq.io/latest/qmod-reference/language-reference/generative-descriptions/).\n", "\n", "---" ] @@ -58,7 +58,7 @@ "\n", "The argument of the `main` function is a qubit array named `x`. Initalize it to the state $|0000000000\\rangle$ with $10$ qubits using the `allocate` function.\n", "\n", - "After that, by allowing generative functions by setting `@qfunc(generative=True)`, it is possible to use the length of the qubit array `x` as a classical variable, and apply quantum operations over qubits dynamically, using Python's `if` and `for` statements over the qmod `x.len` quantity, according to the pre-defined rule of flipping the state of the even qubits. \n", + "After that, it is possible to use the length of the qubit array `x` as a classical variable, and apply quantum operations over qubits dynamically, using Python's `if` and `for` statements over the qmod `x.len` quantity, according to the pre-defined rule of flipping the state of the even qubits. \n", "\n", "The condition of whether `i` is even evaluated is using the `%` modulo operation, which calculates the reminder of the integer `i` divided by $2$." ] @@ -72,7 +72,7 @@ "from classiq import *\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def main(x: Output[QArray]):\n", " allocate(10, x)\n", " print(x.len)\n", @@ -184,7 +184,7 @@ "from classiq import *\n", "\n", "\n", - "@qfunc(generative=True)\n", + "@qfunc\n", "def main(x: Output[QArray]):\n", " allocate(24, x)\n", " k = 0\n", @@ -227,9 +227,9 @@ "- **Quantum control flow**: Qmod fully supports Python types such as `float`, `int` and `bool` variables within Qmod control flow, such as `repeat` and `if-for` statements.\n", "\n", "\n", - "### Generative Functions in Qmod \n", + "### Generative Descriptions in Qmod \n", "\n", - "Generative functions are employed to enhance hybrid quantum-classical workflows by treating quantum objects into classical variables: \n", + "Generative descriptions are employed to enhance hybrid quantum-classical workflows by treating quantum objects into classical variables: \n", "\n", "- **Dynamic iteration**: Using `range` and `for` loops integration with Qmod types, such as `len`. \n", "- **Conditional operations**: Using `if` statements controlled by Qmod types." From 6db1f49a3640966c1027b91a644a86dc4ab51f83 Mon Sep 17 00:00:00 2001 From: Ori Roth Date: Wed, 30 Apr 2025 11:43:53 +0300 Subject: [PATCH 2/2] Fix notebook bug --- .../cooling_systems_optimization.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb b/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb index f64ad5ef1..4cbaae5bb 100644 --- a/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb +++ b/applications/automotive/cooling_systems_optimization/cooling_systems_optimization.ipynb @@ -271,7 +271,7 @@ " repeat(\n", " data.len,\n", " lambda k: if_(\n", - " logical_and(k != highest_nonzero_bit, get_bit(j_updated, k)),\n", + " logical_and(k != highest_nonzero_bit, get_bit(j_updated, k) == 1),\n", " lambda: CX(data[highest_nonzero_bit], data[k]),\n", " lambda: IDENTITY(data),\n", " ),\n",