"""Describe and decode a small graph optimization problem.

This lesson starts before a variational optimizer: define a typed graph,
inspect its stable variable order, and decode one candidate bitstring. Keeping
problem semantics separate from an algorithm makes later QAOA results auditable.
"""

from __future__ import annotations

import json

from cascaqit.problems import GraphProblemIR, decode_graph_bitstring


def main() -> None:
    """Create a path graph and decode one independent-set candidate."""
    # Positions are explicit problem facts; they are not inferred hardware placement.
    graph = GraphProblemIR.from_edges(
        problem_id="lesson.optimization.beginner",
        positions={"a": (0.0, 0.0), "b": (5.0, 0.0), "c": (10.0, 0.0)},
        edges=(("a", "b"), ("b", "c")),
    )

    # The candidate uses the graph's frozen variable order.
    decoded = decode_graph_bitstring(graph, "101")
    candidates = [decode_graph_bitstring(graph, f"{value:03b}") for value in range(8)]
    feasible = [item for item in candidates if item["is_independent"]]
    maximum_size = max(item["selection_size"] for item in feasible)
    payload = {
        "track": "optimization_researcher",
        "level": "beginner",
        "lesson": "graph_problem",
        "facts": {
            "node_order": list(graph.nodes),
            "edges": [list(edge) for edge in graph.edges],
            "bitstring": decoded["bitstring"],
            "selected_nodes": list(decoded["selected_nodes"]),
            "feasible": decoded["is_independent"],
            "candidates": [
                {
                    "bitstring": item["bitstring"],
                    "size": item["selection_size"],
                    "feasible": item["is_independent"],
                    "violating_edges": item["violating_edges"],
                }
                for item in candidates
            ],
            "maximum_independent_set_size": maximum_size,
            "optimal_bitstrings": [
                item["bitstring"]
                for item in feasible
                if item["selection_size"] == maximum_size
            ],
        },
        "boundaries": {
            "hardware_execution": False,
            "cloud_execution": False,
            "network_accessed": False,
            "credentials_loaded": False,
        },
    }
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()
