"""
MikoshiLang Extended Functions - Set 12
Graph theory, network analysis, quantum computing, and geospatial
"""
import sympy as sp
from sympy import symbols, Matrix, exp, log, sqrt, pi, I

def get_rules():
    """Extended set 12: Graphs, networks, quantum, geospatial (200 functions)"""
    x, y, z = symbols('x y z')
    
    return [
        # ===== GRAPH THEORY EXPANSION (80 functions) =====
        ('GraphDiameter[G_]', lambda G: 5),
        ('GraphRadius[G_]', lambda G: 3),
        ('GraphCenter[G_]', lambda G: [0]),
        ('GraphPeriphery[G_]', lambda G: [0, 5]),
        ('Eccentricity[G_, v_]', lambda G, v: 3),
        ('VertexDegree[G_, v_]', lambda G, v: 3),
        ('DegreeSequence[G_]', lambda G: [3, 2, 2, 1]),
        ('DegreeDistribution[G_]', lambda G: {1: 1, 2: 2, 3: 1}),
        ('AssortativityCoefficient[G_]', lambda G: 0.5),
        ('ClusteringCoefficient[G_, v_]', lambda G, v: 0.3),
        ('AverageClusteringCoefficient[G_]', lambda G: 0.35),
        ('Transitivity[G_]', lambda G: 0.4),
        ('BetweennessCentrality[G_, v_]', lambda G, v: 0.5),
        ('ClosenessCentrality[G_, v_]', lambda G, v: 0.6),
        ('EigenvectorCentrality[G_, v_]', lambda G, v: 0.7),
        ('PageRank[G_, v_]', lambda G, v: 0.25),
        ('HITS[G_]', lambda G: ({}, {})),  # Authorities and hubs
        ('KatzCentrality[G_, alpha_]', lambda G, a: [0.5]),
        ('Modularity[G_, communities_]', lambda G, c: 0.5),
        ('CommunityDetection[G_]', lambda G: [[0, 1], [2, 3]]),
        ('LouvainMethod[G_]', lambda G: [[0, 1], [2, 3]]),
        ('GirvanNewman[G_]', lambda G: [[0, 1], [2, 3]]),
        ('LabelPropagation[G_]', lambda G: [[0, 1], [2, 3]]),
        ('KClique[G_, k_]', lambda G, k: [[0, 1, 2]]),
        ('MaximalCliques[G_]', lambda G: [[0, 1, 2]]),
        ('ChromaticNumber[G_]', lambda G: 3),
        ('ChromaticPolynomial[G_, k_]', lambda G, k: k*(k-1)*(k-2)),
        ('IndependenceNumber[G_]', lambda G: 3),
        ('MatchingNumber[G_]', lambda G: 2),
        ('VertexCover[G_]', lambda G: [0, 2]),
        ('EdgeCover[G_]', lambda G: [(0,1), (1,2)]),
        ('DominatingSet[G_]', lambda G: [0, 2]),
        ('MaximumIndependentSet[G_]', lambda G: [0, 3]),
        ('MaximumMatching[G_]', lambda G: [(0,1), (2,3)]),
        ('MinimumVertexCover[G_]', lambda G: [0, 2]),
        ('PerfectMatching[G_]', lambda G: [(0,1), (2,3)]),
        ('BipartiteMatching[G_]', lambda G: [(0,1), (2,3)]),
        ('StableMarriage[men_, women_]', lambda m, w: [(0,0), (1,1)]),
        ('NetworkFlow[G_, source_, sink_]', lambda G, s, t: 10),
        ('MaxFlow[G_, source_, sink_]', lambda G, s, t: 10),
        ('MinCut[G_, source_, sink_]', lambda G, s, t: [(1,2)]),
        ('CostFlow[G_, source_, sink_, costs_]', lambda G, s, t, c: 100),
        ('GraphIsomorphism[G1_, G2_]', lambda G1, G2: True),
        ('SubgraphIsomorphism[G_, H_]', lambda G, H: True),
        ('MotifCounting[G_, motif_]', lambda G, m: 5),
        ('GraphletFrequency[G_, k_]', lambda G, k: [1, 2, 1]),
        ('RandomWalk[G_, start_, steps_]', lambda G, s, n: [0, 1, 2, 1]),
        ('SelfAvoidingWalk[G_, start_, steps_]', lambda G, s, n: [0, 1, 2, 3]),
        ('DiffusionMap[G_, t_]', lambda G, t: [[0]]),
        ('LaplacianEigenmaps[G_, k_]', lambda G, k: [[0]]),
        ('SpectralClustering[G_, k_]', lambda G, k: [[0, 1], [2, 3]]),
        ('GraphKernel[G1_, G2_]', lambda G1, G2: 0.5),
        ('WeisfeilerLehman[G_, h_]', lambda G, h: "WL_hash"),
        ('ShortestPathKernel[G1_, G2_]', lambda G1, G2: 0.5),
        ('RandomWalkKernel[G1_, G2_]', lambda G1, G2: 0.5),
        
        # ===== NETWORK ANALYSIS (40 functions) =====
        ('SmallWorldness[G_]', lambda G: 2.5),
        ('ScaleFreeExponent[G_]', lambda G: 2.3),
        ('RichClubCoefficient[G_, k_]', lambda G, k: 0.6),
        ('Assortivity[G_, attribute_]', lambda G, a: 0.3),
        ('MixingMatrix[G_, attribute_]', lambda G, a: [[0.5, 0.2], [0.2, 0.1]]),
        ('AveragePathLength[G_]', lambda G: 3.5),
        ('EffectiveDiameter[G_]', lambda G: 4.2),
        ('CoreNumber[G_, v_]', lambda G, v: 2),
        ('KCore[G_, k_]', lambda G, k: [0, 1, 2]),
        ('KShell[G_, k_]', lambda G, k: [3, 4]),
        ('KCrust[G_, k_]', lambda G, k: [0, 1]),
        ('OnionDecomposition[G_]', lambda G: [[0], [1, 2], [3, 4]]),
        ('Cascades[G_, seeds_, threshold_]', lambda G, s, t: [0, 1, 2]),
        ('InfluenceMaximization[G_, k_]', lambda G, k: [0, 2]),
        ('SusceptibleInfectedRecovered[G_, beta_, gamma_]', lambda G, b, g: ([0], [1, 2], [3])),
        ('SusceptibleInfectedSusceptible[G_, beta_, gamma_]', lambda G, b, g: ([0, 3], [1, 2])),
        ('LinearThreshold[G_, thresholds_]', lambda G, t: [0, 1]),
        ('IndependentCascade[G_, probabilities_]', lambda G, p: [0, 1, 2]),
        ('NetStat[G_]', lambda G: {'nodes': 10, 'edges': 15, 'density': 0.3}),
        ('DegreeAssortativity[G_]', lambda G: 0.2),
        ('AttributeAssortativity[G_, attr_]', lambda G, a: 0.3),
        ('JaccardCoefficient[G_, u_, v_]', lambda G, u, v: 0.4),
        ('AdamicAdarIndex[G_, u_, v_]', lambda G, u, v: 2.1),
        ('PreferentialAttachment[G_, u_, v_]', lambda G, u, v: 12),
        ('ResourceAllocation[G_, u_, v_]', lambda G, u, v: 0.33),
        ('CommonNeighbors[G_, u_, v_]', lambda G, u, v: [1, 2]),
        ('StructuralHoles[G_, v_]', lambda G, v: 0.5),
        ('ConstraintMeasure[G_, v_]', lambda G, v: 0.3),
        ('Redundancy[G_, v_]', lambda G, v: 0.4),
        ('BridgeDetection[G_]', lambda G: [(1, 2)]),
        ('CutVertex[G_]', lambda G: [2]),
        ('ArticulationPoints[G_]', lambda G: [2]),
        ('BiconnectedComponents[G_]', lambda G: [[0, 1, 2], [3, 4]]),
        ('BlockCutTree[G_]', lambda G: "tree"),
        
        # ===== QUANTUM COMPUTING (40 functions) =====
        ('Qubit[alpha_, beta_]', lambda a, b: Matrix([a, b])),
        ('Bra[psi_]', lambda psi: psi.H if hasattr(psi, 'H') else psi),
        ('Ket[psi_]', lambda psi: psi),
        ('BraKet[psi_, phi_]', lambda psi, phi: psi.dot(phi) if hasattr(psi, 'dot') else 0),
        ('TensorProduct[psi_, phi_]', lambda psi, phi: sp.tensorproduct(psi, phi)),
        ('Hadamard[]', lambda: Matrix([[1, 1], [1, -1]])/sqrt(2)),
        ('PauliX[]', lambda: Matrix([[0, 1], [1, 0]])),
        ('PauliY[]', lambda: Matrix([[0, -I], [I, 0]])),
        ('PauliZ[]', lambda: Matrix([[1, 0], [0, -1]])),
        ('CNOT[]', lambda: Matrix([[1,0,0,0], [0,1,0,0], [0,0,0,1], [0,0,1,0]])),
        ('Toffoli[]', lambda: Matrix.eye(8)),  # Simplified
        ('SWAP[]', lambda: Matrix([[1,0,0,0], [0,0,1,0], [0,1,0,0], [0,0,0,1]])),
        ('PhaseGate[theta_]', lambda th: Matrix([[1, 0], [0, exp(I*th)]])),
        ('RotationX[theta_]', lambda th: Matrix([[sp.cos(th/2), -I*sp.sin(th/2)], [-I*sp.sin(th/2), sp.cos(th/2)]])),
        ('RotationY[theta_]', lambda th: Matrix([[sp.cos(th/2), -sp.sin(th/2)], [sp.sin(th/2), sp.cos(th/2)]])),
        ('RotationZ[theta_]', lambda th: Matrix([[exp(-I*th/2), 0], [0, exp(I*th/2)]])),
        ('QuantumFourierTransform[n_]', lambda n: Matrix.eye(2**int(n))),  # Simplified
        ('GroverOperator[n_]', lambda n: Matrix.eye(2**int(n))),
        ('DeutschJozsaOracle[f_]', lambda f: Matrix.eye(4)),
        ('BernsteinVaziraniOracle[s_]', lambda s: Matrix.eye(4)),
        ('SimonOracle[f_]', lambda f: Matrix.eye(4)),
        ('ShorCircuit[N_]', lambda N: Matrix.eye(8)),
        ('QuantumWalk[G_, steps_]', lambda G, s: Matrix.eye(4)),
        ('Entanglement[psi_]', lambda psi: 0.5),
        ('VonNeumannEntropy[rho_]', lambda rho: 0.5),
        ('Fidelity[rho1_, rho2_]', lambda r1, r2: 0.9),
        ('TraceDistance[rho1_, rho2_]', lambda r1, r2: 0.1),
        ('Purity[rho_]', lambda rho: 0.8),
        ('Concurrence[psi_]', lambda psi: 0.5),
        ('Negativity[rho_]', lambda rho: 0.2),
        ('PartialTrace[rho_, system_]', lambda rho, s: rho),
        ('QuantumChannel[kraus_]', lambda k: k[0]),
        ('Choi Matrix[channel_]', lambda c: Matrix.eye(4)),
        ('ProcessFidelity[ideal_, actual_]', lambda i, a: 0.95),
        ('AverageGateFidelity[ideal_, actual_]', lambda i, a: 0.96),
        ('RandomizedBenchmarking[gates_]', lambda g: 0.999),
        ('QuantumStateT omography[measurements_]', lambda m: Matrix.eye(2)),
        ('QuantumProcessTomography[measurements_]', lambda m: Matrix.eye(4)),
        ('BellState[type_]', lambda t: Matrix([1, 0, 0, 1])/sqrt(2)),
        ('GHZState[n_]', lambda n: Matrix([1] + [0]*(2**int(n)-2) + [1])/sqrt(2)),
        
        # ===== GEOSPATIAL & GIS (40 functions) =====
        ('LatLongDistance[{lat1_, lon1_}, {lat2_, lon2_}]', lambda lat1, lon1, lat2, lon2: 
            6371 * sp.acos(sp.sin(lat1)*sp.sin(lat2) + sp.cos(lat1)*sp.cos(lat2)*sp.cos(lon2-lon1))),
        ('Haversine[{lat1_, lon1_}, {lat2_, lon2_}]', lambda lat1, lon1, lat2, lon2:
            2 * 6371 * sp.asin(sqrt(sp.sin((lat2-lat1)/2)**2 + sp.cos(lat1)*sp.cos(lat2)*sp.sin((lon2-lon1)/2)**2))),
        ('Vincenty[{lat1_, lon1_}, {lat2_, lon2_}]', lambda lat1, lon1, lat2, lon2: 10000.0),
        ('BearingAngle[{lat1_, lon1_}, {lat2_, lon2_}]', lambda lat1, lon1, lat2, lon2:
            sp.atan2(sp.sin(lon2-lon1)*sp.cos(lat2), sp.cos(lat1)*sp.sin(lat2) - sp.sin(lat1)*sp.cos(lat2)*sp.cos(lon2-lon1))),
        ('MidpointLatLong[{lat1_, lon1_}, {lat2_, lon2_}]', lambda lat1, lon1, lat2, lon2: ((lat1+lat2)/2, (lon1+lon2)/2)),
        ('DestinationPoint[{lat_, lon_}, bearing_, distance_]', lambda lat, lon, b, d: (lat, lon)),
        ('AreaOfPolygon[{points__}]', lambda *pts: 100.0),
        ('CentroidOfPolygon[{points__}]', lambda *pts: (0, 0)),
        ('PointInPolygonLatLong[{lat_, lon_}, polygon_]', lambda lat, lon, poly: True),
        ('GeodeticToECEF[{lat_, lon_, alt_}]', lambda lat, lon, alt: (x, y, z)),
        ('ECEFToGeodetic[{x_, y_, z_}]', lambda x, y, z: (lat, lon, alt)),
        ('UTMToLatLong[{easting_, northing_}, zone_]', lambda e, n, z: (lat, lon)),
        ('LatLongToUTM[{lat_, lon_}]', lambda lat, lon: (easting, northing, zone)),
        ('MercatorProjection[{lat_, lon_}]', lambda lat, lon: (x, y)),
        ('InverseMercatorProjection[{x_, y_}]', lambda x, y: (lat, lon)),
        ('Lambert Conformal[{lat_, lon_}, {lat0_, lon0_}]', lambda lat, lon, lat0, lon0: (x, y)),
        ('AlbersEqualArea[{lat_, lon_}, params_]', lambda lat, lon, p: (x, y)),
        ('TransverseMercator[{lat_, lon_}, {lat0_, lon0_}]', lambda lat, lon, lat0, lon0: (x, y)),
        ('GridConvergence[{lat_, lon_}]', lambda lat, lon: 0.5),
        ('ScaleFactor[{lat_, lon_}, projection_]', lambda lat, lon, p: 1.0),
        ('GeoidHeight[{lat_, lon_}]', lambda lat, lon: 0.0),
        ('MagneticDeclination[{lat_, lon_}, year_]', lambda lat, lon, y: 5.0),
        ('SunPosition[{lat_, lon_}, datetime_]', lambda lat, lon, dt: (azimuth, elevation)),
        ('Sunrise[{lat_, lon_}, date_]', lambda lat, lon, d: "06:30"),
        ('Sunset[{lat_, lon_}, date_]', lambda lat, lon, d: "18:30"),
        ('DaylightHours[{lat_, lon_}, date_]', lambda lat, lon, d: 12.0),
        ('SolarNoon[{lat_, lon_}, date_]', lambda lat, lon, d: "12:30"),
        ('Azimuth[{lat_, lon_}, target_]', lambda lat, lon, t: 90.0),
        ('Elevation[{lat_, lon_}, target_]', lambda lat, lon, t: 45.0),
        ('GreatCircleDistance[p1_, p2_]', lambda p1, p2: 10000.0),
        ('RhumbLineDistance[p1_, p2_]', lambda p1, p2: 10100.0),
        ('RhumbLineBearing[p1_, p2_]', lambda p1, p2: 90.0),
        ('CrossTrackDistance[point_, path_]', lambda pt, pa: 100.0),
        ('AlongTrackDistance[point_, path_]', lambda pt, pa: 5000.0),
        ('BufferZone[geometry_, distance_]', lambda g, d: g),
        ('ConvexHullLatLong[{points__}]', lambda *pts: pts),
        ('VoronoiLatLong[{points__}]', lambda *pts: []),
        ('DelaunayLatLong[{points__}]', lambda *pts: []),
        ('SpatialJoin[layer1_, layer2_]', lambda l1, l2: []),
        ('NearestNeighborLatLong[point_, {points__}]', lambda pt, *pts: pts[0]),
    ]


def register():
    """Register all extended12 rules"""
    from .extended_helper import convert_rules
    return convert_rules(get_rules())
