import { type DiceExpression } from './dice-expression'; import { UnsupportedExactAnalysis } from './unsupported-exact'; import { type Expression, type ParameterSpec, type Program, type Value } from './program'; import { type AnalysisBudget } from './program-stats-support'; import { type AnalysisEnv, type ExprAnalysis, type ProgramAnalysisResult } from './program-stats-types'; export declare function countVariableUses(program: Program): Map; export { UnsupportedExactAnalysis }; export declare function makeAnalysisEnv(useCounts: Map, diceRegistry?: Map, strictExact?: boolean, budget?: AnalysisBudget): AnalysisEnv; /** Walk a program once and collect every `dice @name [...]` declaration * into a registry keyed by name. Mirrors the registry the Evaluator * builds, so the exact analyzer sees the same face lists at analysis * time. */ export declare function buildDiceRegistry(program: Program): Map; export declare function analyzeParameterDeclaration(name: string, spec: ParameterSpec, overrides: Record, env: AnalysisEnv): ExprAnalysis; export declare function nonRandomAnalysis(): ExprAnalysis; export declare function analyzeNumberLiteral(expr: Extract, _env: AnalysisEnv): ExprAnalysis; export declare function analyzeBooleanLiteral(expr: Extract, _env: AnalysisEnv): ExprAnalysis; export declare function analyzeStringLiteral(expr: Extract, _env: AnalysisEnv): ExprAnalysis; export declare function analyzeVariableRef(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeUnaryExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeRoundExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeBinaryExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeIfExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeRecordExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeArrayExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeRepeatExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeFieldAccess(expr: Extract, env: AnalysisEnv): ExprAnalysis; /** * `primary default fallback`. When the primary's distribution carries no "no * value" (`UNDEFINED_SENTINEL`) mass, the fallback can never fire, so the * result is the primary's distribution unchanged. * * When undefined mass *is* present — a missing field, an out-of-range index, * or a division by zero under the `default` — and the fallback is a constant, * substitute it for exactly that mass via `mapSymDist`, which preserves the * primary's joint/source structure (so the substitution stays exact and * correctly correlated). A non-constant (random / correlated) fallback defers * to Monte Carlo (null symDist); the evaluator applies `default` correctly on * that path. This is what makes a non-zero `default` on a structurally-absent * field — e.g. `$pool.despair default 7` — exact and consistent with the * roll-time evaluator, now that `analyzeFieldAccess` is strict. */ export declare function analyzeDefaultExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeIndexAccess(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeSliceAccess(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeMatchExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeComprehensionExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeFoldExpr(expr: Extract, env: AnalysisEnv): ExprAnalysis; export declare function analyzeExpr(expr: Expression, env: AnalysisEnv): ExprAnalysis; export declare function constantIntegerInEnv(expr: Expression, env: AnalysisEnv): number | null; export declare function diceExpressionHasVarRef(expr: Expression | DiceExpression): boolean; export declare function analyzeProgram(program: Program, parameters?: Record, options?: { strictExact?: boolean; budget?: AnalysisBudget; }): ProgramAnalysisResult;