Metadata-Version: 2.5
Name: flaq
Version: 0.2.0
Summary: Solve-spec compiler for quantum research: feasibility decisions before execution.
Project-URL: Homepage, https://flaq.io
Project-URL: Organization, https://github.com/flaq-io
Author: Flaq Technologies
License: Apache-2.0
License-File: LICENSE
Keywords: quantum computing,quantum software,resource estimation,vqe
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# flaq

Compile a quantum research spec into a **priced, refusable plan** — before
anything runs.

Flaq does not generate code and hope. It takes a solve spec, decides whether
the stated accuracy is reachable inside the stated budget, and says so:

```
synthesize(spec) -> SolvePlan   # what it will cost and achieve
                 -> Refusal     # or exactly how much it is short
```

There is no third output. A plan without a prediction is not a plan.

## Why

An LLM asked to "solve this with VQE" will always produce something. It has no
cost model, so it cannot tell you the run will need 40,000 shots when you
budgeted 10,000. Flaq turns that into a compile-time decision:

```python
>>> from flaq import synthesize
>>> synthesize(spec)
Refusal(reason='ACCURACY_UNREACHABLE',
        violated=('budget.max_shots_total',),
        minimal_relaxation={'budget.max_shots_total': 40000})
```

A refusal is a return value, not an exception: *"not within this budget"* is an
answer, and it is more useful than a plausible-looking circuit.

## Install

```bash
pip install flaq
```

## Usage

```python
from flaq import (
    AccuracyBudget, BackendProfile, PauliTerm, ResourceBudget, SolveSpec, synthesize,
)

spec = SolveSpec(
    observable=(PauliTerm(coefficient=1.0, pauli="ZZ"),),
    n_qubits=2,
    accuracy=AccuracyBudget(
        epsilon=0.01,
        allocations={"statistical": 0.005},   # error priced before execution
        safety_factor=1.0,
    ),
    budget=ResourceBudget(max_shots_total=100_000),
    backend=BackendProfile(name="simulator", max_qubits=20),
)

result = synthesize(spec)
# SolvePlan(spec_id='3f2a…', required_shots=40000,
#           predicted_statistical_error=0.003162…)
```

## What the numbers mean

The only error source priced analytically in 0.2.0 is the statistical one, using
a bound that holds for any state:

```
eps_stat <= sqrt( sum_i |h_i|^2 / shots )
```

`required_shots` is therefore a **sufficient** ceiling, not a tight estimate. It
ignores `1 - <P_i>^2` (which can only reduce the cost) and ignores iteration
count entirely. Tightness arrives with the cost model in a later version; until
then a refusal means *"provably impossible"*, and a plan means *"provably
sufficient"*.

`minimal_relaxation` is exact for the same reason: it is the value that makes
`synthesize` succeed.

## Guarantees

- **Deterministic.** `spec_id` is a content hash, stable across term order and
  float noise. The same spec always compiles to the same plan.
- **Refusal before execution.** Budget and backend checks happen at compile
  time; nothing is discovered halfway through a run.
- **Spec errors are errors.** An inconsistent spec (negative allocation,
  overspent error budget, Pauli length mismatch, particle sector out of range)
  raises `SpecError` rather than being compiled around.
- **Zero runtime dependencies**, standard library only.

## Scope

0.2.0 is the specification and refusal core. Not yet included: method
catalogues, iterative cost models, ansatz/optimisation error handling, backend
error rates, execution and acceptance reporting.

## License

Apache-2.0
