"""
MikoshiLang Extended Functions - Set 32
Chemical engineering, process control, and reaction engineering
"""
import sympy as sp
from sympy import symbols, sqrt, exp, log, pi, sin, cos

def get_rules():
    """Extended set 32: Chemical engineering (150 functions)"""
    T, P, n, V = symbols('T P n V')
    
    return [
        # ===== THERMODYNAMICS (35 functions) =====
        ('IdealGasEquation[P_, V_, n_, R_, T_]', lambda P, V, n, R, T: P*V - n*R*T),
        ('VanDerWaalsEquation[P_, V_, n_, a_, b_, R_, T_]', lambda P, V, n, a, b, R, T: (P + n**2*a/V**2)*(V - n*b) - n*R*T),
        ('RedlichKwongEOS[P_, V_, T_, a_, b_]', lambda P, V, T, a, b: P - sp.Symbol('R')*T/(V - b) + a/(sqrt(T)*V*(V + b))),
        ('PengRobinsonEOS[P_, V_, T_, a_, b_]', lambda P, V, T, a, b: P - sp.Symbol('R')*T/(V - b) + a/(V*(V + b) + b*(V - b))),
        ('CompressibilityFactor[P_, V_, n_, R_, T_]', lambda P, V, n, R, T: P*V/(n*R*T)),
        ('FugacityCoefficient[phi_]', lambda phi: phi),
        ('ActivityCoefficient[gamma_]', lambda gamma: gamma),
        ('ExcessGibbsEnergy[G_E_]', lambda GE: GE),
        ('RaoultLaw[x_, P_sat_]', lambda x, Psat: x*Psat),
        ('HenryLaw[x_, H_]', lambda x, H: x*H),
        ('EquilibriumConstant[K_]', lambda K: K),
        ('VaporLiquidEquilibrium[y_, x_, K_]', lambda y, x, K: y - K*x),
        ('BubblePointTemperature[x_, P_sat_]', lambda x, Psat: sum(xi*Psati for xi, Psati in zip(x, Psat))),
        ('DewPointTemperature[y_, P_sat_]', lambda y, Psat: 1/sum(yi/Psati for yi, Psati in zip(y, Psat))),
        ('FlashCalculation[z_, K_, beta_]', lambda z, K, beta: sum(zi*(Ki - 1)/(1 + beta*(Ki - 1)) for zi, Ki in zip(z, K))),
        ('RachfordRiceEquation[z_, K_, beta_]', lambda z, K, beta: sum(zi*(Ki - 1)/(1 + beta*(Ki - 1)) for zi, Ki in zip(z, K))),
        ('AntoineEquation[A_, B_, C_, T_]', lambda A, B, C, T: 10**(A - B/(T + C))),
        ('ClausiusClapeyronEquation[P1_, P2_, T1_, T2_, delta_H_]', lambda P1, P2, T1, T2, dH: log(P2/P1) - dH/sp.Symbol('R')*(1/T2 - 1/T1)),
        ('VaporPressureCurve[T_, Tc_, Pc_]', lambda T, Tc, Pc: Pc*exp((1 - Tc/T)*sp.Symbol('B'))),
        ('AcentriFactor[Pr_, Tr_]', lambda Pr, Tr: -log(Pr, 10) - 1 if Tr == 0.7 else sp.Symbol('omega')),
        ('CriticalProperties[Tc_, Pc_, Vc_]', lambda Tc, Pc, Vc: (Tc, Pc, Vc)),
        ('ReducedTemperature[T_, Tc_]', lambda T, Tc: T/Tc),
        ('ReducedPressure[P_, Pc_]', lambda P, Pc: P/Pc),
        ('LeeKeslerMethod[Tr_, Pr_, omega_]', lambda Tr, Pr, omega: sp.Symbol('Z')),
        ('CorrespondingStates[substance1_, substance2_]', lambda s1, s2: s1 == s2),
        ('HeatCapacityIdealGas[T_, A_, B_, C_, D_]', lambda T, A, B, C, D: A + B*T + C*T**2 + D*T**3),
        ('EnthalpyOfFormation[delta_Hf_]', lambda dHf: dHf),
        ('EnthalpyOfReaction[products_, reactants_]', lambda prod, react: sum(prod) - sum(react)),
        ('GibbsFreeEnergyChange[delta_H_, T_, delta_S_]', lambda dH, T, dS: dH - T*dS),
        ('EquilibriumConstantThermo[delta_G_, R_, T_]', lambda dG, R, T: exp(-dG/(R*T))),
        ('VanHoffEquation[K1_, K2_, T1_, T2_, delta_H_]', lambda K1, K2, T1, T2, dH: log(K2/K1) - dH/sp.Symbol('R')*(1/T2 - 1/T1)),
        ('MaxwellRelations[dS_dV_, dP_dT_]', lambda dSdV, dPdT: dSdV == dPdT),
        ('JouleThomsonCoefficient[dT_dP_]', lambda dTdP: dTdP),
        ('InversionTemperature[a_, b_, R_]', lambda a, b, R: 2*a/(b*R)),
        ('ThrottlingProcess[H1_, H2_]', lambda H1, H2: H1 - H2),
        
        # ===== REACTION ENGINEERING (35 functions) =====
        ('ReactionRate[k_, C_]', lambda k, C: k*C),
        ('ArrheniusEquation[A_, Ea_, R_, T_]', lambda A, Ea, R, T: A*exp(-Ea/(R*T))),
        ('ActivationEnergy[k1_, k2_, T1_, T2_, R_]', lambda k1, k2, T1, T2, R: -R*log(k2/k1)/(1/T2 - 1/T1)),
        ('ReactionOrder[n_]', lambda n: n),
        ('ElementaryReaction[rate_]', lambda r: r),
        ('FirstOrderReaction[k_, C_]', lambda k, C: k*C),
        ('SecondOrderReaction[k_, CA_, CB_]', lambda k, CA, CB: k*CA*CB),
        ('ZeroOrderReaction[k_]', lambda k: k),
        ('HalfLife[k_, order_]', lambda k, n: log(2)/k if n == 1 else (2**(n-1) - 1)/(k*(n - 1)*sp.Symbol('C0')**(n-1))),
        ('IntegratedRateLaw[order_, k_, t_, C0_]', lambda n, k, t, C0: C0*exp(-k*t) if n == 1 else C0/(1 + (n - 1)*k*C0**(n-1)*t)),
        ('Turnover Frequency[rate_, active_sites_]', lambda r, sites: r/sites),
        ('TurnoverNumber[products_, catalyst_, time_]', lambda prod, cat, t: prod/(cat*t)),
        ('CatalyticActivity[conversion_, catalyst_mass_]', lambda X, mcat: X/mcat),
        ('SelectivityReaction[desired_, total_]', lambda des, tot: des/tot),
        ('YieldReaction[product_, reactant_fed_]', lambda prod, react: prod/react),
        ('ConversionReactant[fed_, unreacted_]', lambda fed, unr: (fed - unr)/fed),
        ('SpaceTime[V_, v0_]', lambda V, v0: V/v0),
        ('SpaceVelocity[v0_, V_]', lambda v0, V: v0/V),
        ('ResidenceTime[V_, Q_]', lambda V, Q: V/Q),
        ('BatchReactorDesign[C_, C0_, k_, t_]', lambda C, C0, k, t: C0*exp(-k*t)),
        ('CSTRDesign[C0_, C_, k_, tau_]', lambda C0, C, k, tau: C0/(1 + k*tau)),
        ('PFRDesign[C0_, k_, V_, v0_]', lambda C0, k, V, v0: C0*exp(-k*V/v0)),
        ('DamkohlerNumber[k_, tau_]', lambda k, tau: k*tau),
        ('PecletNumber[v_, L_, D_]', lambda v, L, D: v*L/D),
        ('ReactorPerformance[conversion_, selectivity_, yield_]', lambda X, S, Y: (X, S, Y)),
        ('MultipleReactions[rates_]', lambda r: r),
        ('ParallelReactions[k1_, k2_]', lambda k1, k2: k1 + k2),
        ('SeriesReactions[k1_, k2_]', lambda k1, k2: (k1, k2)),
        ('ReversibleReaction[kf_, kr_, Keq_]', lambda kf, kr, Keq: kf/kr - Keq),
        ('EquilibriumConversion[Keq_, feed_]', lambda Keq, feed: Keq/(1 + Keq)),
        ('AutocatalyticReaction[k_, CA_, CB_]', lambda k, CA, CB: k*CA*CB),
        ('ChainReaction[initiation_, propagation_, termination_]', lambda init, prop, term: (init, prop, term)),
        ('FreeRadicalPolymerization[initiator_, monomer_]', lambda I, M: sqrt(sp.Symbol('ki')*I)*M),
        ('EnzymeKinetics[Vmax_, Km_, S_]', lambda Vmax, Km, S: Vmax*S/(Km + S)),
        ('MichaelisMentenKinetics[Vmax_, Km_, S_]', lambda Vmax, Km, S: Vmax*S/(Km + S)),
        
        # ===== MASS TRANSFER (30 functions) =====
        ('FicksFirstLawDiffusion[D_, dC_dx_]', lambda D, dCdx: -D*dCdx),
        ('FicksSecondLawDiffusion[D_, d2C_dx2_]', lambda D, d2Cdx2: D*d2Cdx2),
        ('DiffusionCoefficient[D0_, Ea_, R_, T_]', lambda D0, Ea, R, T: D0*exp(-Ea/(R*T))),
        ('MassTransferCoefficient[k_]', lambda k: k),
        ('SherwoodNumber[k_, L_, D_]', lambda k, L, D: k*L/D),
        ('SchmidtNumber[mu_, rho_, D_]', lambda mu, rho, D: mu/(rho*D)),
        ('MassTransferFlux[k_, delta_C_]', lambda k, dC: k*dC),
        ('ConvectiveMassTransfer[h_m_, A_, delta_C_]', lambda hm, A, dC: hm*A*dC),
        ('MolecularDiffusion[D_, delta_C_, delta_x_]', lambda D, dC, dx: -D*dC/dx),
        ('EquimolarCounterdiffusion[D_AB_, y_A1_, y_A2_, delta_z_]', lambda DAB, yA1, yA2, dz: DAB*(yA1 - yA2)/dz),
        ('FilmTheory[k_]', lambda k: k),
        ('PenetrationTheory[D_, t_]', lambda D, t: 2*sqrt(D/(pi*t))),
        ('SurfaceRenewal[D_, s_]', lambda D, s: sqrt(D*s)),
        ('BoundaryLayerThickness[delta_]', lambda delta: delta),
        ('MassTransferResistance[1_k_]', lambda k: 1/k),
        ('OverallMassTransferCoefficient[K_]', lambda K: K),
        ('TwoFilmTheory[k_L_, k_G_, m_]', lambda kL, kG, m: 1/(1/kL + m/kG)),
        ('HTUHeight[G_, k_, a_]', lambda G, k, a: G/(k*a)),  # Height of Transfer Unit
        ('NTUNumber[y1_, y2_, y_star_]', lambda y1, y2, ystar: sp.integrate(1/(sp.Symbol('y') - ystar), (sp.Symbol('y'), y1, y2))),  # Number of Transfer Units
        ('ExtractionEfficiency[C_feed_, C_raffinate_]', lambda Cfeed, Craff: (Cfeed - Craff)/Cfeed),
        ('DistributionCoefficient[C_organic_, C_aqueous_]', lambda Corg, Caq: Corg/Caq),
        ('StageEfficiency[actual_, theoretical_]', lambda actual, theor: actual/theor),
        ('MurphreeEfficiency[y_out_, y_in_, y_eq_]', lambda yout, yin, yeq: (yout - yin)/(yeq - yin)),
        ('McCabeThieleMethod[x_, y_, q_]', lambda x, y, q: (x, y)),
        ('MinimumRefluxRatio[xD_, xF_, y_eq_]', lambda xD, xF, yeq: (xD - yeq)/(yeq - xF)),
        ('ActualRefluxRatio[R_min_, factor_]', lambda Rmin, f: Rmin*f),
        ('NumberOfTheoreticalStages[xF_, xD_, xB_, R_]', lambda xF, xD, xB, R: sp.Symbol('N')),
        ('FeedStageLocation[q_]', lambda q: q),
        ('DistillationColumnDiameter[V_, rho_, u_]', lambda V, rho, u: sqrt(4*V/(pi*u*rho))),
        ('FloodingVelocity[rho_L_, rho_V_]', lambda rhoL, rhoV: sqrt((rhoL - rhoV)/rhoV)),
        
        # ===== HEAT TRANSFER (25 functions) =====
        ('FouriersLaw[k_, dT_dx_]', lambda k, dTdx: -k*dTdx),
        ('ConvectiveHeatTransferCoeff[h_]', lambda h: h),
        ('NusseltNumber[h_, L_, k_]', lambda h, L, k: h*L/k),
        ('OverallHeatTransferCoeff[U_]', lambda U: U),
        ('LogMeanTempDifference[delta_T1_, delta_T2_]', lambda dT1, dT2: (dT1 - dT2)/log(dT1/dT2)),
        ('HeatExchangerArea[Q_, U_, LMTD_]', lambda Q, U, LMTD: Q/(U*LMTD)),
        ('HeatExchangerEffectivenessNTU[epsilon_, NTU_, C_]', lambda eps, NTU, C: eps),
        ('NTUHeatExchanger[UA_, Cmin_]', lambda UA, Cmin: UA/Cmin),
        ('HeatCapacityRate[m_dot_, Cp_]', lambda mdot, Cp: mdot*Cp),
        ('CounterflowHeatExchanger[NTU_, C_]', lambda NTU, C: (1 - exp(-NTU*(1 - C)))/(1 - C*exp(-NTU*(1 - C)))),
        ('ParallelFlowHeatExchanger[NTU_, C_]', lambda NTU, C: (1 - exp(-NTU*(1 + C)))/(1 + C)),
        ('ShellTubeHeatExchanger[N_tubes_, D_, L_]', lambda N, D, L: N*pi*D*L),
        ('FoulingResistance[Rf_]', lambda Rf: Rf),
        ('FinEfficiency[tanh_mL_, mL_]', lambda tanhmL, mL: tanhmL/mL),
        ('FinParameter[h_, P_, k_, A_]', lambda h, P, k, A: sqrt(h*P/(k*A))),
        ('ExtendedSurfaceEffectiveness[Q_fin_, Q_noFin_]', lambda Qfin, Qno: Qfin/Qno),
        ('StefanBoltzmannLawHeat[epsilon_, sigma_, A_, T_]', lambda eps, sig, A, T: eps*sig*A*T**4),
        ('RadiativeHeatExchange[F12_, A1_, T1_, T2_]', lambda F12, A1, T1, T2: sp.Symbol('sigma')*A1*F12*(T1**4 - T2**4)),
        ('ViewFactor[F12_]', lambda F12: F12),
        ('EmissivitySurface[epsilon_]', lambda eps: eps),
        ('AbsorptivitySurface[alpha_]', lambda alpha: alpha),
        ('ReflectivitySurface[rho_]', lambda rho: rho),
        ('GreyBodyRadiation[epsilon_, T_]', lambda eps, T: eps*sp.Symbol('sigma')*T**4),
        ('RadiationShield[N_shields_]', lambda N: 1/(N + 1)),
        ('CriticalInsulationRadius[k_, h_]', lambda k, h: k/h),
        
        # ===== PROCESS CONTROL (25 functions) =====
        ('ProcessGain[K_]', lambda K: K),
        ('TimeConstant[tau_]', lambda tau: tau),
        ('DeadTime[theta_]', lambda theta: theta),
        ('FirstOrderProcess[K_, tau_, s_]', lambda K, tau, s: K/(tau*s + 1)),
        ('SecondOrderProcess[K_, zeta_, omega_n_, s_]', lambda K, zeta, omegan, s: K*omegan**2/(s**2 + 2*zeta*omegan*s + omegan**2)),
        ('PIDController[Kp_, Ki_, Kd_, e_]', lambda Kp, Ki, Kd, e: Kp*e + Ki*sp.Symbol('int_e') + Kd*sp.Symbol('de_dt')),
        ('ProportionalGain[Kp_]', lambda Kp: Kp),
        ('IntegralTime[Ti_]', lambda Ti: Ti),
        ('DerivativeTime[Td_]', lambda Td: Td),
        ('ZieglerNicholsTuning[Ku_, Pu_]', lambda Ku, Pu: (0.6*Ku, Pu/2, Pu/8)),
        ('CohenCoonTuning[K_, tau_, theta_]', lambda K, tau, theta: sp.Symbol('Kp')),
        ('ClosedLoopStability[poles_]', lambda poles: all(sp.re(p) < 0 for p in poles)),
        ('OpenLoopGainProcess[G_, H_]', lambda G, H: G*H),
        ('CharacteristicEquation[1_GH_]', lambda GH: 1 + GH),
        ('StabilityMarginGain[GM_]', lambda GM: GM),
        ('StabilityMarginPhase[PM_]', lambda PM: PM),
        ('OffsetSteadyState[r_, y_ss_]', lambda r, yss: r - yss),
        ('DisturbanceRejection[G_d_, G_, H_]', lambda Gd, G, H: Gd/(1 + G*H)),
        ('SetpointTracking[G_, H_]', lambda G, H: G/(1 + G*H)),
        ('SensitivityFunction[S_]', lambda S: 1/(1 + sp.Symbol('GH'))),
        ('ComplementarySensitivity[T_]', lambda T: sp.Symbol('GH')/(1 + sp.Symbol('GH'))),
        ('RobustStabilityProcess[delta_, T_]', lambda delta, T: delta*T < 1),
        ('ModelPredictiveControlHorizon[N_]', lambda N: N),
        ('ControlHorizon[M_]', lambda M: M),
        ('PredictionHorizon[P_]', lambda P: P),
    ]


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