classiq 0.33.0__py3-none-any.whl → 0.35.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/_internals/api_wrapper.py +61 -23
- classiq/_internals/client.py +4 -1
- classiq/_internals/jobs.py +9 -2
- classiq/applications_model_constructors/grover_model_constructor.py +1 -1
- classiq/execution/__init__.py +9 -2
- classiq/execution/jobs.py +84 -11
- classiq/executor.py +3 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +17 -0
- classiq/interface/backend/pydantic_backend.py +8 -0
- classiq/interface/backend/quantum_backend_providers.py +15 -1
- classiq/interface/chemistry/ground_state_problem.py +1 -1
- classiq/interface/chemistry/operator.py +198 -0
- classiq/interface/execution/jobs.py +28 -0
- classiq/interface/executor/execution_request.py +2 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -0
- classiq/interface/generator/arith/arithmetic_param_getters.py +12 -0
- classiq/interface/generator/arith/binary_ops.py +34 -0
- classiq/interface/generator/expressions/expression.py +3 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +12 -2
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -0
- classiq/interface/generator/function_params.py +4 -0
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +2 -2
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +42 -105
- classiq/interface/generator/generated_circuit.py +8 -44
- classiq/interface/generator/generated_circuit_data.py +2 -11
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/quantum_function_call.py +1 -1
- classiq/interface/hardware.py +2 -0
- classiq/interface/ide/show.py +1 -14
- classiq/interface/model/bind_operation.py +10 -0
- classiq/interface/model/handle_binding.py +18 -0
- classiq/interface/model/model.py +12 -3
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +2 -1
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +9 -6
- classiq/interface/model/quantum_function_call.py +9 -339
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/server/routes.py +8 -6
- classiq/model/function_handler.pyi +86 -85
- classiq/qmod/__init__.py +2 -2
- classiq/qmod/builtins/__init__.py +8 -0
- classiq/{interface/model/clients/qmod/qmod_builtins.py → qmod/builtins/functions.py} +46 -165
- classiq/qmod/builtins/operations.py +19 -0
- classiq/qmod/builtins/structs.py +128 -0
- classiq/qmod/declaration_inferrer.py +34 -17
- classiq/qmod/model_state_container.py +6 -3
- classiq/qmod/qmod_parameter.py +24 -8
- classiq/qmod/qmod_variable.py +4 -4
- classiq/qmod/quantum_callable.py +2 -2
- classiq/qmod/quantum_expandable.py +7 -3
- classiq/qmod/quantum_function.py +9 -9
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/METADATA +1 -1
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/RECORD +56 -55
- classiq/interface/model/clients/qmod/__init__.py +0 -0
- classiq/interface/model/semantics.py +0 -15
- classiq/qmod/qmod_builtins.py +0 -4
- /classiq/interface/{model/clients → execution}/__init__.py +0 -0
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/WHEEL +0 -0
@@ -1,59 +1,23 @@
|
|
1
|
-
import functools
|
2
1
|
import itertools
|
3
2
|
import re
|
4
|
-
from
|
5
|
-
from typing import (
|
6
|
-
TYPE_CHECKING,
|
7
|
-
Any,
|
8
|
-
Collection,
|
9
|
-
Dict,
|
10
|
-
Iterable,
|
11
|
-
List,
|
12
|
-
Mapping,
|
13
|
-
Match,
|
14
|
-
Optional,
|
15
|
-
Sequence,
|
16
|
-
Set,
|
17
|
-
Tuple,
|
18
|
-
Union,
|
19
|
-
)
|
3
|
+
from typing import Any, Dict, List, Mapping, Optional, Sequence, Set, Union
|
20
4
|
|
21
5
|
import pydantic
|
22
|
-
from pydantic import BaseModel
|
6
|
+
from pydantic import BaseModel
|
23
7
|
|
24
|
-
from classiq.interface.generator import function_param_list, function_params as f_params
|
25
8
|
from classiq.interface.generator.arith.arithmetic import Arithmetic
|
26
9
|
from classiq.interface.generator.control_state import ControlState
|
27
10
|
from classiq.interface.generator.expressions.expression import Expression
|
28
|
-
from classiq.interface.generator.function_params import
|
29
|
-
NAME_REGEX,
|
30
|
-
FunctionParams,
|
31
|
-
PortDirection,
|
32
|
-
)
|
11
|
+
from classiq.interface.generator.function_params import NAME_REGEX
|
33
12
|
from classiq.interface.generator.functions import FunctionDeclaration
|
34
13
|
from classiq.interface.generator.functions.port_declaration import (
|
35
14
|
PortDeclarationDirection,
|
36
15
|
)
|
37
16
|
from classiq.interface.generator.quantum_function_call import (
|
38
17
|
BAD_CALL_NAME_ERROR_MSG,
|
39
|
-
BAD_INPUT_ERROR_MSG,
|
40
|
-
BAD_INPUT_EXPRESSION_MSG,
|
41
|
-
BAD_INPUT_SLICING_MSG,
|
42
|
-
BAD_OUTPUT_ERROR_MSG,
|
43
|
-
BAD_OUTPUT_EXPRESSION_MSG,
|
44
|
-
BAD_OUTPUT_SLICING_MSG,
|
45
|
-
CUSTOM_FUNCTION_SINGLE_IO_ERROR,
|
46
|
-
LEGAL_SLICING,
|
47
18
|
SUFFIX_MARKER,
|
48
19
|
randomize_suffix,
|
49
20
|
)
|
50
|
-
from classiq.interface.generator.slice_parsing_utils import (
|
51
|
-
IO_REGEX,
|
52
|
-
NAME,
|
53
|
-
SLICING,
|
54
|
-
parse_io_slicing,
|
55
|
-
)
|
56
|
-
from classiq.interface.generator.user_defined_function_params import CustomFunction
|
57
21
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
58
22
|
from classiq.interface.model.handle_binding import (
|
59
23
|
HandleBinding,
|
@@ -67,7 +31,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
67
31
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
68
32
|
from classiq.interface.model.validation_handle import get_unique_handle_names
|
69
33
|
|
70
|
-
from classiq.exceptions import
|
34
|
+
from classiq.exceptions import ClassiqError, ClassiqValueError
|
71
35
|
|
72
36
|
|
73
37
|
def _validate_no_duplicated_ports(
|
@@ -143,10 +107,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
143
107
|
description="The function that is called"
|
144
108
|
)
|
145
109
|
params: Dict[str, Expression] = pydantic.Field(default_factory=dict)
|
146
|
-
function_params: f_params.FunctionParams = pydantic.Field(
|
147
|
-
description="The parameters necessary for defining the function",
|
148
|
-
default_factory=CustomFunction,
|
149
|
-
)
|
150
110
|
strict_zero_ios: bool = pydantic.Field(
|
151
111
|
default=True,
|
152
112
|
description="Enables automated qubit allocation for pre-determined zero inputs "
|
@@ -196,7 +156,10 @@ class QuantumFunctionCall(QuantumOperation):
|
|
196
156
|
)
|
197
157
|
|
198
158
|
@property
|
199
|
-
def func_decl(self) ->
|
159
|
+
def func_decl(self) -> QuantumFunctionDeclaration:
|
160
|
+
if self._func_decl is None:
|
161
|
+
raise ClassiqError("Accessing an unresolved quantum function call")
|
162
|
+
|
200
163
|
return self._func_decl
|
201
164
|
|
202
165
|
def set_func_decl(self, fd: Optional[FunctionDeclaration]) -> None:
|
@@ -260,41 +223,13 @@ class QuantumFunctionCall(QuantumOperation):
|
|
260
223
|
if isinstance(function, OperandIdentifier):
|
261
224
|
function = function.name
|
262
225
|
|
263
|
-
params = values.get("function_params")
|
264
|
-
if isinstance(params, CustomFunction):
|
265
|
-
if function == CustomFunction.discriminator() and params.name != "":
|
266
|
-
function = params.name
|
267
|
-
|
268
226
|
suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
|
269
|
-
if not function
|
227
|
+
if not function:
|
270
228
|
return name if name else suffix
|
271
229
|
return f"{function}_{suffix}"
|
272
230
|
|
273
|
-
@pydantic.root_validator(pre=True)
|
274
|
-
def validate_composite_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
275
|
-
if isinstance(values.get("unitary_params"), CustomFunction) and not values.get(
|
276
|
-
"unitary"
|
277
|
-
):
|
278
|
-
raise ClassiqValueError(
|
279
|
-
"`PhaseEstimation` of a user define function (`CustomFunction`) must receive the function name from the `unitary` field"
|
280
|
-
)
|
281
|
-
return values
|
282
|
-
|
283
|
-
@pydantic.root_validator(pre=True)
|
284
|
-
def _parse_function_params(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
285
|
-
f_params.parse_function_params_values(
|
286
|
-
values=values,
|
287
|
-
params_key="function_params",
|
288
|
-
discriminator_key="function",
|
289
|
-
param_classes=function_param_list.function_param_library.param_list,
|
290
|
-
default_parser_class=CustomFunction,
|
291
|
-
)
|
292
|
-
return values
|
293
|
-
|
294
231
|
@property
|
295
232
|
def pos_param_args(self) -> Dict[str, Expression]:
|
296
|
-
if TYPE_CHECKING:
|
297
|
-
assert self.func_decl is not None
|
298
233
|
return dict(
|
299
234
|
zip(
|
300
235
|
self.func_decl.param_decls.keys(),
|
@@ -308,8 +243,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
308
243
|
|
309
244
|
@property
|
310
245
|
def pos_operand_args(self) -> Dict[str, "QuantumOperand"]:
|
311
|
-
if TYPE_CHECKING:
|
312
|
-
assert self.func_decl is not None
|
313
246
|
return dict(
|
314
247
|
zip(
|
315
248
|
self.func_decl.operand_declarations.keys(),
|
@@ -323,8 +256,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
323
256
|
|
324
257
|
@property
|
325
258
|
def pos_port_args(self) -> Dict[str, HandleBinding]:
|
326
|
-
if TYPE_CHECKING:
|
327
|
-
assert self.func_decl is not None
|
328
259
|
return dict(
|
329
260
|
zip(
|
330
261
|
self.func_decl.port_declarations.keys(),
|
@@ -337,8 +268,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
337
268
|
)
|
338
269
|
|
339
270
|
def _update_pos_port_params(self) -> None:
|
340
|
-
if TYPE_CHECKING:
|
341
|
-
assert self.func_decl is not None
|
342
271
|
for name, port_decl in self.func_decl.port_declarations.items():
|
343
272
|
if port_decl.direction == PortDeclarationDirection.Input:
|
344
273
|
self.inputs[name] = self.pos_port_args[name]
|
@@ -352,45 +281,10 @@ class QuantumFunctionCall(QuantumOperation):
|
|
352
281
|
self.operands.update(self.pos_operand_args)
|
353
282
|
self._update_pos_port_params()
|
354
283
|
|
355
|
-
# TODO: note that this checks QuantumFunctionCall input register names
|
356
|
-
# are PARTIAL to FunctionParams input register names, not EQUAL.
|
357
|
-
# We might want to change that.
|
358
|
-
@staticmethod
|
359
|
-
def _validate_input_names(
|
360
|
-
*,
|
361
|
-
params: f_params.FunctionParams,
|
362
|
-
input_names: Collection[str],
|
363
|
-
control_states: List[ControlState],
|
364
|
-
strict_zero_ios: bool,
|
365
|
-
) -> None:
|
366
|
-
(
|
367
|
-
invalid_expressions,
|
368
|
-
invalid_slicings,
|
369
|
-
invalid_names,
|
370
|
-
) = QuantumFunctionCall._get_invalid_ios(
|
371
|
-
expressions=input_names,
|
372
|
-
params=params,
|
373
|
-
io=PortDirection.Input,
|
374
|
-
control_states=control_states,
|
375
|
-
strict_zero_ios=strict_zero_ios,
|
376
|
-
)
|
377
|
-
error_msg = []
|
378
|
-
if invalid_expressions:
|
379
|
-
error_msg.append(f"{BAD_INPUT_EXPRESSION_MSG}: {invalid_expressions}")
|
380
|
-
if invalid_names:
|
381
|
-
error_msg.append(f"{BAD_INPUT_ERROR_MSG}: {invalid_names}")
|
382
|
-
if invalid_slicings:
|
383
|
-
error_msg.append(f"{BAD_INPUT_SLICING_MSG}: {invalid_slicings}")
|
384
|
-
if error_msg:
|
385
|
-
raise ValueError("\n".join(error_msg))
|
386
|
-
|
387
284
|
def resolve_function_decl(
|
388
285
|
self,
|
389
286
|
function_dict: Mapping[str, FunctionDeclaration],
|
390
287
|
) -> None:
|
391
|
-
if not isinstance(self.function_params, CustomFunction):
|
392
|
-
return
|
393
|
-
|
394
288
|
if self._func_decl is None:
|
395
289
|
func_decl = function_dict.get(self.func_name)
|
396
290
|
if func_decl is None:
|
@@ -399,9 +293,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
399
293
|
)
|
400
294
|
self.set_func_decl(func_decl)
|
401
295
|
|
402
|
-
if TYPE_CHECKING:
|
403
|
-
assert self.func_decl is not None
|
404
|
-
|
405
296
|
if self.positional_args:
|
406
297
|
self._reduce_positional_args_to_keywords()
|
407
298
|
|
@@ -432,228 +323,10 @@ class QuantumFunctionCall(QuantumOperation):
|
|
432
323
|
), "when using the Arithmetic function, assign to the expression result register via the target parameter instead of the strict_zero_ios flag"
|
433
324
|
return strict_zero_ios
|
434
325
|
|
435
|
-
@pydantic.validator("control_states")
|
436
|
-
def _validate_control_states(
|
437
|
-
cls, control_states: List[ControlState], values: Dict[str, Any]
|
438
|
-
) -> List[ControlState]:
|
439
|
-
control_names = [ctrl_state.name for ctrl_state in control_states]
|
440
|
-
function_params = values.get("function_params")
|
441
|
-
strict_zero_ios = values.get("strict_zero_ios")
|
442
|
-
if not (
|
443
|
-
isinstance(function_params, FunctionParams)
|
444
|
-
and isinstance(strict_zero_ios, bool)
|
445
|
-
):
|
446
|
-
return control_states
|
447
|
-
all_input_names = [
|
448
|
-
*function_params.inputs_full(strict_zero_ios=strict_zero_ios),
|
449
|
-
*control_names,
|
450
|
-
]
|
451
|
-
all_output_names = [*function_params.outputs, *control_names]
|
452
|
-
if any(
|
453
|
-
cls._has_repetitions(name_list)
|
454
|
-
for name_list in (control_names, all_input_names, all_output_names)
|
455
|
-
):
|
456
|
-
raise ClassiqControlError()
|
457
|
-
return control_states
|
458
|
-
|
459
326
|
@staticmethod
|
460
327
|
def _has_repetitions(name_list: Sequence[str]) -> bool:
|
461
328
|
return len(set(name_list)) < len(name_list)
|
462
329
|
|
463
|
-
@staticmethod
|
464
|
-
def _validate_slices(
|
465
|
-
io: PortDirection,
|
466
|
-
input_names: Collection[str],
|
467
|
-
fp: FunctionParams,
|
468
|
-
strict_zero_ios: bool,
|
469
|
-
control_states: List[ControlState],
|
470
|
-
) -> None:
|
471
|
-
name_slice_pairs = [parse_io_slicing(input) for input in input_names]
|
472
|
-
slices_dict: Dict[str, List[slice]] = defaultdict(list)
|
473
|
-
for name, slice_obj in name_slice_pairs:
|
474
|
-
slices_dict[name].append(slice_obj)
|
475
|
-
|
476
|
-
fp_inputs = (
|
477
|
-
fp.inputs_full(strict_zero_ios)
|
478
|
-
if (io == PortDirection.Input)
|
479
|
-
else fp.outputs
|
480
|
-
)
|
481
|
-
widths = {name: reg.size for name, reg in fp_inputs.items()}
|
482
|
-
control_names = {state.name for state in control_states}
|
483
|
-
|
484
|
-
for name in slices_dict:
|
485
|
-
if name in control_names:
|
486
|
-
continue
|
487
|
-
assert name in widths, "Name not in widths"
|
488
|
-
if not QuantumFunctionCall._register_validate_slices(
|
489
|
-
slices_dict[name], widths[name]
|
490
|
-
):
|
491
|
-
raise ValueError(BAD_INPUT_SLICING_MSG)
|
492
|
-
|
493
|
-
@staticmethod
|
494
|
-
def _register_validate_slices(slices: List[slice], reg_width: int) -> bool:
|
495
|
-
widths_separated = [len(range(reg_width)[reg_slice]) for reg_slice in slices]
|
496
|
-
# examples: slice(0), slice(5,None) when width <= 5, slice(5,3)
|
497
|
-
empty_slices = 0 in widths_separated
|
498
|
-
|
499
|
-
max_stop = max(reg_slice.stop or 0 for reg_slice in slices)
|
500
|
-
out_of_range = max_stop > reg_width
|
501
|
-
|
502
|
-
all_widths_separated = sum(widths_separated)
|
503
|
-
all_indices = set(
|
504
|
-
itertools.chain.from_iterable(
|
505
|
-
range(reg_width)[reg_slice] for reg_slice in slices
|
506
|
-
)
|
507
|
-
)
|
508
|
-
all_widths_combined = len(all_indices)
|
509
|
-
overlapping_slices = all_widths_combined != all_widths_separated
|
510
|
-
|
511
|
-
return not any((empty_slices, out_of_range, overlapping_slices))
|
512
|
-
|
513
|
-
@pydantic.validator("inputs")
|
514
|
-
def _validate_inputs(
|
515
|
-
cls, inputs: Mapping[str, HandleBinding], values: Dict[str, Any]
|
516
|
-
) -> Mapping[str, HandleBinding]:
|
517
|
-
params: Optional[FunctionParams] = values.get("function_params")
|
518
|
-
strict_zero_ios: bool = values.get("strict_zero_ios", True)
|
519
|
-
control_states: List[ControlState] = values.get("control_states", list())
|
520
|
-
if params is None:
|
521
|
-
return dict()
|
522
|
-
if isinstance(params, CustomFunction):
|
523
|
-
if not isinstance(inputs, dict):
|
524
|
-
raise ValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
525
|
-
return inputs
|
526
|
-
|
527
|
-
cls._validate_input_names(
|
528
|
-
params=params,
|
529
|
-
input_names=inputs.keys(),
|
530
|
-
control_states=control_states,
|
531
|
-
strict_zero_ios=strict_zero_ios,
|
532
|
-
)
|
533
|
-
|
534
|
-
cls._validate_slices(
|
535
|
-
PortDirection.Input,
|
536
|
-
inputs.keys(),
|
537
|
-
params,
|
538
|
-
strict_zero_ios,
|
539
|
-
control_states,
|
540
|
-
)
|
541
|
-
|
542
|
-
return inputs
|
543
|
-
|
544
|
-
@staticmethod
|
545
|
-
def _validate_output_names(
|
546
|
-
*,
|
547
|
-
params: f_params.FunctionParams,
|
548
|
-
output_names: Collection[str],
|
549
|
-
control_states: List[ControlState],
|
550
|
-
strict_zero_ios: bool,
|
551
|
-
) -> None:
|
552
|
-
(
|
553
|
-
invalid_expressions,
|
554
|
-
invalid_slicings,
|
555
|
-
invalid_names,
|
556
|
-
) = QuantumFunctionCall._get_invalid_ios(
|
557
|
-
expressions=output_names,
|
558
|
-
params=params,
|
559
|
-
io=PortDirection.Output,
|
560
|
-
control_states=control_states,
|
561
|
-
strict_zero_ios=strict_zero_ios,
|
562
|
-
)
|
563
|
-
error_msg = []
|
564
|
-
if invalid_expressions:
|
565
|
-
error_msg.append(f"{BAD_OUTPUT_EXPRESSION_MSG}: {invalid_expressions}")
|
566
|
-
if invalid_names:
|
567
|
-
error_msg.append(f"{BAD_OUTPUT_ERROR_MSG}: {invalid_names}")
|
568
|
-
if invalid_slicings:
|
569
|
-
error_msg.append(f"{BAD_OUTPUT_SLICING_MSG}: {invalid_slicings}")
|
570
|
-
if error_msg:
|
571
|
-
raise ValueError("\n".join(error_msg))
|
572
|
-
|
573
|
-
@pydantic.validator("outputs")
|
574
|
-
def _validate_outputs(
|
575
|
-
cls, outputs: Mapping[str, HandleBinding], values: Dict[str, Any]
|
576
|
-
) -> Mapping[str, HandleBinding]:
|
577
|
-
params = values.get("function_params")
|
578
|
-
strict_zero_ios: bool = values.get("strict_zero_ios", True)
|
579
|
-
control_states = values.get("control_states", list())
|
580
|
-
if params is None:
|
581
|
-
return outputs
|
582
|
-
if isinstance(params, CustomFunction):
|
583
|
-
if not isinstance(outputs, dict):
|
584
|
-
raise ValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
585
|
-
return outputs
|
586
|
-
|
587
|
-
cls._validate_output_names(
|
588
|
-
params=params,
|
589
|
-
output_names=outputs.keys(),
|
590
|
-
control_states=control_states,
|
591
|
-
strict_zero_ios=strict_zero_ios,
|
592
|
-
)
|
593
|
-
|
594
|
-
cls._validate_slices(
|
595
|
-
PortDirection.Output,
|
596
|
-
outputs.keys(),
|
597
|
-
params,
|
598
|
-
strict_zero_ios,
|
599
|
-
control_states,
|
600
|
-
)
|
601
|
-
|
602
|
-
return outputs
|
603
|
-
|
604
|
-
@staticmethod
|
605
|
-
def _get_invalid_ios(
|
606
|
-
*,
|
607
|
-
expressions: Iterable[str],
|
608
|
-
params: f_params.FunctionParams,
|
609
|
-
io: f_params.PortDirection,
|
610
|
-
control_states: List[ControlState],
|
611
|
-
strict_zero_ios: bool,
|
612
|
-
) -> Tuple[List[str], List[str], List[str]]:
|
613
|
-
expression_matches: Iterable[Optional[Match]] = map(
|
614
|
-
functools.partial(re.fullmatch, IO_REGEX), expressions
|
615
|
-
)
|
616
|
-
|
617
|
-
valid_matches: List[Match] = []
|
618
|
-
invalid_expressions: List[str] = []
|
619
|
-
for expression, expression_match in zip(expressions, expression_matches):
|
620
|
-
invalid_expressions.append(
|
621
|
-
expression
|
622
|
-
) if expression_match is None else valid_matches.append(expression_match)
|
623
|
-
|
624
|
-
invalid_slicings: List[str] = []
|
625
|
-
invalid_names: List[str] = []
|
626
|
-
valid_names = frozenset(
|
627
|
-
params.inputs_full(strict_zero_ios)
|
628
|
-
if io == PortDirection.Input
|
629
|
-
else params.outputs
|
630
|
-
)
|
631
|
-
for match in valid_matches:
|
632
|
-
name = match.groupdict().get(NAME)
|
633
|
-
if name is None:
|
634
|
-
raise AssertionError("Input/output name validation error")
|
635
|
-
|
636
|
-
slicing = match.groupdict().get(SLICING)
|
637
|
-
if slicing is not None and re.fullmatch(LEGAL_SLICING, slicing) is None:
|
638
|
-
invalid_slicings.append(match.string)
|
639
|
-
|
640
|
-
if name in valid_names:
|
641
|
-
continue
|
642
|
-
elif all(state.name != name for state in control_states):
|
643
|
-
invalid_names.append(name)
|
644
|
-
|
645
|
-
return invalid_expressions, invalid_slicings, invalid_names
|
646
|
-
|
647
|
-
def get_param_exprs(self) -> Dict[str, Expression]:
|
648
|
-
if isinstance(self.function_params, CustomFunction):
|
649
|
-
return self.params
|
650
|
-
else:
|
651
|
-
return {
|
652
|
-
name: Expression(expr=raw_expr)
|
653
|
-
for name, raw_expr in self.function_params
|
654
|
-
if self.function_params.is_field_gen_param(name)
|
655
|
-
}
|
656
|
-
|
657
330
|
@pydantic.root_validator()
|
658
331
|
def validate_handles(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
659
332
|
inputs = values.get("inputs", dict())
|
@@ -666,9 +339,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
666
339
|
|
667
340
|
return values
|
668
341
|
|
669
|
-
class Config:
|
670
|
-
extra = Extra.forbid
|
671
|
-
|
672
342
|
|
673
343
|
class QuantumLambdaFunction(BaseModel):
|
674
344
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Mapping, Union
|
2
2
|
|
3
|
-
from pydantic import BaseModel
|
3
|
+
from pydantic import BaseModel, Extra
|
4
4
|
|
5
5
|
from classiq.interface.model.handle_binding import (
|
6
6
|
HandleBinding,
|
@@ -10,7 +10,8 @@ from classiq.interface.model.handle_binding import (
|
|
10
10
|
|
11
11
|
|
12
12
|
class QuantumStatement(BaseModel):
|
13
|
-
|
13
|
+
class Config:
|
14
|
+
extra = Extra.forbid
|
14
15
|
|
15
16
|
|
16
17
|
class QuantumOperation(QuantumStatement):
|
@@ -3,6 +3,10 @@ CHEMISTRY_PREFIX = "/chemistry"
|
|
3
3
|
LEGACY_EXECUTE_PREFIX = "/execute"
|
4
4
|
EXECUTION_PREFIX = "/execution"
|
5
5
|
|
6
|
+
SYNTHESIS_SERVICE_PREFIX = "/synthesis/v1"
|
7
|
+
|
8
|
+
EXECUTION_SERVICE_PREFIX = "/execution/v1"
|
9
|
+
|
6
10
|
ANALYZER_CIRCUIT_PAGE = "circuit"
|
7
11
|
DEFAULT_IDE_FE_APP = "https://platform.classiq.io/"
|
8
12
|
|
@@ -34,9 +38,7 @@ DATA_DOG_EVENT_TASK_FULL_PATH = f"{ANALYZER_PREFIX}{DATA_DOG_EVENT_TASK}"
|
|
34
38
|
|
35
39
|
IDE_QASM_TASK = f"{TASKS_SUFFIX}/generated_circuit_from_qasm"
|
36
40
|
IDE_QASM_FULL_PATH = f"{ANALYZER_PREFIX}{IDE_QASM_TASK}"
|
37
|
-
IDE_EXECUTION_RESULTS_PATH = f"/results{LEGACY_EXECUTE_PREFIX}"
|
38
41
|
TASKS_GENERATE_SUFFIX = TASKS_SUFFIX + "/generate"
|
39
|
-
SEMANTICS_CHECK_SUFFIX = TASKS_SUFFIX + "/semantic_checks"
|
40
42
|
TASKS_VISUALIZE_SUFFIX = TASKS_SUFFIX + "/visualize"
|
41
43
|
TASKS_SOLVE_SUFFIX = "/tasks/solve"
|
42
44
|
MODEL_GENERATE_PREFIX = "/generate_model"
|
@@ -50,10 +52,10 @@ TASKS_GENERATE_FULL_PATH = TASKS_GENERATE_SUFFIX
|
|
50
52
|
TASKS_SOLVE_EXACT_SUFFIX = "/tasks/solve_exact"
|
51
53
|
TASKS_UCC_OPERATORS_SUFFIX = "/tasks/ucc_operators"
|
52
54
|
|
53
|
-
TASKS_GET_MAX_CUT_MODEL = "/tasks/get_max_cut_model"
|
54
55
|
|
55
56
|
EXECUTION_JOBS_SUFFIX = "/jobs"
|
56
57
|
EXECUTION_JOBS_FULL_PATH = EXECUTION_PREFIX + EXECUTION_JOBS_SUFFIX
|
58
|
+
EXECUTION_SERVICE_JOBS_FULL_PATH = EXECUTION_SERVICE_PREFIX + EXECUTION_JOBS_SUFFIX
|
57
59
|
EXECUTE_QUANTUM_PROGRAM_FULL_PATH = LEGACY_EXECUTE_PREFIX + QUANTUM_PROGRAM_SUFFIX
|
58
60
|
EXECUTE_ESTIMATE_FULL_PATH = LEGACY_EXECUTE_PREFIX + ESTIMATE_SUFFIX
|
59
61
|
|
@@ -61,12 +63,12 @@ ANALYZER_FULL_PATH = ANALYZER_PREFIX + TASKS_SUFFIX
|
|
61
63
|
ANALYZER_RB_FULL_PATH = ANALYZER_PREFIX + TASK_RB_SUFFIX
|
62
64
|
GENERATE_RESOURCE_ESTIMATOR_REPORT = "/resource_estimator_report"
|
63
65
|
|
64
|
-
|
66
|
+
GENERATE_HAMILTONIAN_SUFFIX = "/generate_hamiltonian"
|
67
|
+
GENERATE_HAMILTONIAN_FULL_PATH = SYNTHESIS_SERVICE_PREFIX + GENERATE_HAMILTONIAN_SUFFIX
|
68
|
+
|
65
69
|
CHEMISTRY_GENERATE_UCC_OPERATORS_FULL_PATH = (
|
66
70
|
CHEMISTRY_PREFIX + TASKS_UCC_OPERATORS_SUFFIX
|
67
71
|
)
|
68
|
-
CHEMISTRY_SOLVE_EXACT_FULL_PATH = CHEMISTRY_PREFIX + TASKS_SOLVE_EXACT_SUFFIX
|
69
|
-
CHEMISTRY_SOLVE_FULL_PATH = CHEMISTRY_PREFIX + TASKS_SOLVE_SUFFIX
|
70
72
|
|
71
73
|
FINANCE_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/finance"
|
72
74
|
|