"""
MikoshiLang Extended Functions - Set 35
Mining engineering, geological exploration, and mineral processing
"""
import sympy as sp
from sympy import symbols, sqrt, exp, log, pi, sin, cos

def get_rules():
    """Extended set 35: Mining and mineral processing (150 functions)"""
    x, y, z = symbols('x y z')
    
    return [
        # ===== ROCK MECHANICS (35 functions) =====
        ('UCSStrength[sigma_c_]', lambda sc: sc),  # Uniaxial compressive strength
        ('TensileStrength[sigma_t_]', lambda st: st),
        ('CohesionRock[c_]', lambda c: c),
        ('FrictionAngleRock[phi_]', lambda phi: phi),
        ('MohrCoulombCriterion[sigma1_, sigma3_, c_, phi_]', lambda s1, s3, c, phi: (s1 - s3)/2 - c*cos(phi) - (s1 + s3)/2*sin(phi)),
        ('HoekBrownCriterion[sigma1_, sigma3_, m_, s_, sigmac_]', lambda s1, s3, m, s, sc: s1 - s3 - sc*sqrt(m*s3/sc + s)),
        ('RockQualityDesignation[RQD_]', lambda RQD: RQD),
        ('RockMassRating[RMR_]', lambda RMR: RMR),
        ('QSystemRating[Q_]', lambda Q: Q),
        ('GeologicalStrengthIndex[GSI_]', lambda GSI: GSI),
        ('YoungModulusRock[E_]', lambda E: E),
        ('PoissonRatioRock[nu_]', lambda nu: nu),
        ('BulkModulusRock[K_]', lambda K: K),
        ('ShearModulusRock[G_]', lambda G: G),
        ('DeformationModulus[Em_]', lambda Em: Em),
        ('ElasticWaveVelocity[Vp_]', lambda Vp: Vp),
        ('ShearWaveVelocity[Vs_]', lambda Vs: Vs),
        ('DynamicElasticModulus[rho_, Vp_, Vs_]', lambda rho, Vp, Vs: rho*Vs**2*(3*Vp**2 - 4*Vs**2)/(Vp**2 - Vs**2)),
        ('InSituStress[sigma_v_]', lambda sv: sv),
        ('OverburdenPressure[rho_, g_, h_]', lambda rho, g, h: rho*g*h),
        ('LateralEarthPressure[K0_, sigma_v_]', lambda K0, sv: K0*sv),
        ('TerzaghiEffectiveStress[sigma_, u_]', lambda sig, u: sig - u),
        ('PoreWaterPressure[rho_w_, g_, h_]', lambda rhow, g, h: rhow*g*h),
        ('FailureEnvelope[tau_, sigma_]', lambda tau, sig: tau),
        ('PrincipalStress[sigma1_, sigma2_, sigma3_]', lambda s1, s2, s3: (s1, s2, s3)),
        ('DeviatoricStress[sigma1_, sigma3_]', lambda s1, s3: s1 - s3),
        ('MeanStress[sigma1_, sigma2_, sigma3_]', lambda s1, s2, s3: (s1 + s2 + s3)/3),
        ('StrainEnergy[sigma_, epsilon_]', lambda sig, eps: sig*eps/2),
        ('PlasticityIndex[LL_, PL_]', lambda LL, PL: LL - PL),
        ('LiquidityIndex[w_, PL_, PI_]', lambda w, PL, PI: (w - PL)/PI),
        ('SoilClassification[gravel_, sand_, silt_, clay_]', lambda g, sa, si, c: sp.Symbol('USCS')),
        ('AtterbergLimits[LL_, PL_, SL_]', lambda LL, PL, SL: (LL, PL, SL)),
        ('UndrainedShearStrength[su_]', lambda su: su),
        ('ConsolidationSettlement[Cc_, H_, sigma0_, delta_sigma_]', lambda Cc, H, s0, ds: Cc*H/(1 + sp.Symbol('e0'))*log((s0 + ds)/s0)),
        ('TimeFactorConsolidation[Tv_]', lambda Tv: Tv),
        
        # ===== MINE DESIGN (30 functions) =====
        ('PitSlopeAngle[beta_]', lambda beta: beta),
        ('SafetyFactor[resisting_, driving_]', lambda R, D: R/D),
        ('StabilityNumber[H_, gamma_, c_]', lambda H, gamma, c: gamma*H/c),
        ('OpenPitDepth[economic_limit_]', lambda el: el),
        ('StrippingRatio[waste_, ore_]', lambda w, o: w/o),
        ('CutoffGrade[price_, cost_]', lambda p, c: c/p),
        ('BreakevenGrade[total_cost_, recovery_, price_]', lambda tc, rec, p: tc/(rec*p)),
        ('NetPresentValue[cashflows_, discount_rate_]', lambda cf, r: sum(cfi/(1 + r)**i for i, cfi in enumerate(cf))),
        ('InternalRateReturn[NPV_]', lambda NPV: sp.Symbol('IRR')),
        ('PaybackPeriod[investment_, annual_return_]', lambda inv, ret: inv/ret),
        ('ProfitabilityIndex[NPV_, investment_]', lambda NPV, inv: NPV/inv),
        ('OperatingCost[fixed_, variable_, production_]', lambda fixed, var, prod: fixed + var*prod),
        ('CapitalCost[equipment_, infrastructure_]', lambda eq, infra: eq + infra),
        ('TonneKilometer[tonnes_, distance_]', lambda t, d: t*d),
        ('HaulageCost[cost_per_tkm_, tkm_]', lambda c, tkm: c*tkm),
        ('LoadingTime[volume_, bucket_capacity_, cycle_time_]', lambda V, bc, ct: V/bc*ct),
        ('TruckFleetSize[production_, truck_capacity_, trips_per_shift_]', lambda prod, cap, trips: prod/(cap*trips)),
        ('MatchFactor[loader_capacity_, truck_capacity_]', lambda lc, tc: tc/lc),
        ('BenchHeight[H_]', lambda H: H),
        ('BenchWidth[W_]', lambda W: W),
        ('RampGradient[gradient_]', lambda g: g),
        ('HaulRoadDesign[width_, gradient_, radius_]', lambda w, g, r: (w, g, r)),
        ('DrainageSystemMine[flow_]', lambda Q: Q),
        ('VentilationRequirement[Q_air_]', lambda Q: Q),
        ('MethaneDrainage[Q_CH4_]', lambda Q: Q),
        ('GroundSupportDesign[RMR_, span_]', lambda RMR, span: sp.Symbol('support_type')),
        ('RoofBoltDesign[spacing_, length_]', lambda s, l: (s, l)),
        ('ShotcreteThickness[thickness_]', lambda t: t),
        ('CableVoltSupport[capacity_]', lambda cap: cap),
        ('PilllarDesign[width_, height_, safety_factor_]', lambda w, h, sf: w/(h*sf)),
        
        # ===== DRILLING & BLASTING (25 functions) =====
        ('DrillHoleDepth[bench_height_, subdrill_]', lambda H, sd: H + sd),
        ('Burden[hole_diameter_, rock_factor_]', lambda d, rf: rf*d),
        ('Spacing[burden_, ratio_]', lambda B, ratio: B*ratio),
        ('StemingLength[burden_]', lambda B: 0.7*B),
        ('SubDrill[burden_]', lambda B: 0.3*B),
        ('PowderFactor[explosive_weight_, rock_volume_]', lambda W, V: W/V),
        ('SpecificCharge[explosive_, rock_]', lambda exp, rock: exp/rock),
        ('BlastHolePattern[burden_, spacing_]', lambda B, S: B*S),
        ('ExplosiveEnergy[TNT_equivalent_]', lambda TNT: TNT*4.184),  # MJ/kg
        ('VOD[velocity_of_detonation_]', lambda VOD: VOD),  # m/s
        ('Density Explosive[rho_]', lambda rho: rho),
        ('BulkStrength[density_, VOD_]', lambda rho, VOD: rho*VOD**2/(2*1e6)),
        ('WeightStrength[TNT_equiv_percent_]', lambda tnteq: tnteq),
        ('InitiationSystem[delay_]', lambda d: d),
        ('BlastVibration[K_, distance_, charge_]', lambda K, D, W: K*(D/sqrt(W))**(-1.6)),
        ('PeakParticleVelocity[PPV_]', lambda PPV: PPV),
        ('AirOverpressure[P_]', lambda P: P),
        ('FlyRock[distance_]', lambda d: d),
        ('Fragmentation[d50_]', lambda d50: d50),
        ('KuzRamModel[A_, x_, xc_]', lambda A, x, xc: 1 - exp(-(x/xc)**A)),
        ('RosinRammlerDistribution[x_, x0_, n_]', lambda x, x0, n: 1 - exp(-(x/x0)**n)),
        ('SwellFactor[volume_blasted_, volume_insitu_]', lambda Vb, Vi: Vb/Vi),
        ('LoadFactor[tonnes_per_hole_]', lambda tph: tph),
        ('DrillingRate[meters_per_hour_]', lambda mph: mph),
        ('BlastDesignOptimization[cost_, fragmentation_]', lambda c, f: c/f),
        
        # ===== MINERAL PROCESSING (35 functions) =====
        ('CrushingRatio[feed_size_, product_size_]', lambda f, p: f/p),
        ('ReductionRatio[F80_, P80_]', lambda F80, P80: F80/P80),
        ('BondWorkIndex[Wi_]', lambda Wi: Wi),
        ('BondCrushingLaw[Wi_, P80_, F80_]', lambda Wi, P80, F80: 10*Wi*(1/sqrt(P80) - 1/sqrt(F80))),
        ('RittingerLaw[C_, P80_, F80_]', lambda C, P80, F80: C*(1/P80 - 1/F80)),
        ('KicksLaw[C_, P80_, F80_]', lambda C, P80, F80: C*log(F80/P80)),
        ('CircuitLoad[fresh_feed_, circulating_load_]', lambda ff, cl: ff + cl),
        ('CirculatingLoad[recycle_, fresh_feed_]', lambda rec, ff: rec/ff*100),
        ('ClosedCircuitReduction[feed_, product_]', lambda f, p: f/p),
        ('ScreenEfficiency[actual_, theoretical_]', lambda act, th: act/th*100),
        ('ScreenArea[capacity_, unit_area_capacity_]', lambda cap, uac: cap/uac),
        ('ScreeningRate[tonnes_per_hour_]', lambda tph: tph),
        ('UndersizeRecovery[U_]', lambda U: U),
        ('OversizeRecovery[O_]', lambda O: O),
        ('PartitionCoefficient[P_]', lambda P: P),
        ('D50Separation[d50_]', lambda d50: d50),
        ('TrobmpEfficiency[Ep_]', lambda Ep: Ep),
        ('ImperfectionValue[I_]', lambda I: I),
        ('MillPowerDraw[P_]', lambda P: P),
        ('CriticalSpeedMill[D_]', lambda D: 42.3/sqrt(D)),
        ('MillSpeedPercent[actual_, critical_]', lambda act, crit: act/crit*100),
        ('BallCharge[volume_percent_]', lambda vp: vp),
        ('BallSize[feed_size_]', lambda fs: fs/25),
        ('GrindingMedia[balls_, rods_]', lambda b, r: (b, r)),
        ('SlurryDensity[solids_, total_]', lambda s, t: s/t*100),
        ('PulpDensity[percent_solids_]', lambda ps: ps),
        ('DilutionRatio[water_, solids_]', lambda w, s: w/s),
        ('ResidenceTimeGrinding[volume_, flowrate_]', lambda V, Q: V/Q),
        ('GrindingSizereduction[F80_, P80_]', lambda F80, P80: F80/P80),
        ('ClassificationEfficiency[actual_, ideal_]', lambda act, ideal: act/ideal*100),
        ('HydrocycloneD50[d50c_]', lambda d50c: d50c),
        ('CycloneCapacity[Q_]', lambda Q: Q),
        ('OverflowRecovery[Of_]', lambda Of: Of),
        ('UnderflowRecovery[Uf_]', lambda Uf: Uf),
        ('BypassFraction[bypass_]', lambda bp: bp),
        
        # ===== FLOTATION & SEPARATION (25 functions) =====
        ('FlotationRecovery[concentrate_, feed_]', lambda c, f: c/f*100),
        ('ConcentrateGrade[assay_]', lambda a: a),
        ('TailingsGrade[assay_]', lambda a: a),
        ('EnrichmentRatio[concentrate_grade_, feed_grade_]', lambda cg, fg: cg/fg),
        ('MetallurgicalBalance[feed_, concentrate_, tailings_]', lambda f, c, t: f - c - t),
        ('SeparationEfficiency[actual_, ideal_]', lambda act, ideal: act/ideal*100),
        ('CollectorDosage[grams_per_tonne_]', lambda gpt: gpt),
        ('FrotherDosage[grams_per_tonne_]', lambda gpt: gpt),
        ('pHControl[pH_]', lambda pH: pH),
        ('FlotationTime[residence_]', lambda t: t),
        ('AirRate[m3_per_min_]', lambda Q: Q),
        ('FrothDepth[depth_]', lambda d: d),
        ('CellVolume[V_]', lambda V: V),
        ('FlotationBank[num_cells_]', lambda n: n),
        ('CleanerStages[num_stages_]', lambda n: n),
        ('RougherRecovery[R_]', lambda R: R),
        ('ScavengerRecovery[R_]', lambda R: R),
        ('FlotationKinetics[k_, t_]', lambda k, t: 1 - exp(-k*t)),
        ('RecoveryBySize[R_size_]', lambda Rs: Rs),
        ('SelectiveFlotation[mineral1_, mineral2_]', lambda m1, m2: m1/(m1 + m2)),
        ('BulkFlotation[total_sulfides_]', lambda ts: ts),
        ('DifferentialFlotation[mineral_sequence_]', lambda seq: seq),
        ('GravityRecovery[concentrate_, feed_]', lambda c, f: c/f*100),
        ('MagneticSeparation[magnetic_fraction_]', lambda mf: mf),
        ('ElectrostaticSeparation[conducting_, non_conducting_]', lambda cond, noncond: cond/(cond + noncond)),
    ]

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