prodigy.analysis.result

Analysis results (JSON format)

build_result() runs an AnalysisSession and turns everything it recorded into an AnalysisResult. AnalysisResult.to_json() is the exchange format between Prodigy and its front ends (prodigy analyze --json, the web GUI, a language server). Its top-level keys:

schema, prodigy_version, status, error,
program      variables, parameters, constants, functions, loops, queries
input        distribution, engine, normalize, decisions
distribution closed_form, latex, variables, parameters, finite_support, mass,
             error_probability, expectations, marginals
bounds       kind, residual_mass, explanation
queries      kind, expr, value, lower, upper, bound, line, data
loops        id, line, cond, strategy, params, kind, residual_mass, certificates, ...
steps, warnings, log, timing

Exact values are strings in Prodigy’s notation; every exact value that is a number also comes as ..._float.

Sound intervals

Each query carries lower and upper. What they mean depends on the strategies that were used for the loops (bounds.kind):

  • exact: lower = upper = value.

  • lower: the computed distribution μ_N lies coefficient-wise below the exact output distribution μ, and at most the residual mass r is unaccounted for (mass still inside a loop after the last iteration, summed over all loops). For an event φ, μ_N(φ) ≤ μ(φ) ≤ μ_N(φ) + r. With conditioning, Prodigy divides by D = 1 − (known violation mass); the residual is rescaled by 1/D at the same moment, and μ_N(φ)/D ≤ μ(φ)/(1 − err) ≤ (μ_N(φ) + r)/D still holds, whatever the unaccounted mass does later (terminate in φ, outside φ, violate an observation, or diverge). No termination assumption is involved. Expectations of monotone, non-negative expressions get the lower bound only (the upper bound is ∞ while r > 0).

  • upper: the computed distribution lies coefficient-wise above μ (Park’s lemma); with conditioning the violation mass is over-approximated as well, so values are upper bounds.

  • unknown: no guaranteed direction (e.g. lower and upper approximations were mixed, or a side condition could not be checked); values are reported without interval.

prodigy_version()[source]

The version of prodigy-ppl, taken from the Git tag v<version> when it was built or installed.

It comes from the package metadata, or, when the sources run without being installed, from prodigy/_version.py, which every build writes (see [tool.hatch.build.hooks.vcs]).

Return type:

str

sym(value)[source]

Parses Prodigy’s string notation (1/3, p^2, \infty) into sympy.

Parameters:

value (Any)

Return type:

Expr

to_float(expr)[source]
Parameters:

expr (Any)

Return type:

float | None

show(expr)[source]

Prodigy’s notation for an exact value (^ for powers, \infty).

Parameters:

expr (Any)

Return type:

str | None

exact_and_float(value)[source]
Parameters:

value (Any)

Return type:

Tuple[str | None, float | None]

to_sympy(dist)[source]
Parameters:

dist (Distribution)

Return type:

Expr | None

to_latex(dist)[source]
Parameters:

dist (Distribution)

Return type:

str | None

univariate_table(dist, variable, limit, *, kind='exact', residual=0, max_finite_terms=2000)[source]

The first limit coefficients of the marginal of variable.

Finite marginals are listed completely (up to max_finite_terms states); infinite ones by series expansion around 0.

Parameters:
Return type:

Dict[str, Any]

joint_table(dist, limit)[source]

All states of a finite distribution, sorted, if there are at most limit of them.

Parameters:
Return type:

Dict[str, Any] | None

class QueryResult(kind, expr, value=None, value_float=None, lower=None, lower_float=None, upper=None, upper_float=None, bound='exact', note='', data=dict(), index=0, line=None, column=None)[source]

Bases: object

The answer to one query of the program (?Pr, ?Ex, !Print, …).

Parameters:
kind: str

probability, marginal, expectation, print, plot or optimization.

expr: str | None
value: str | None = None
value_float: float | None = None
lower: str | None = None
lower_float: float | None = None
upper: str | None = None
upper_float: float | None = None
bound: str = 'exact'
note: str = ''
data: Dict[str, Any]
index: int = 0
line: int | None = None
column: int | None = None
to_json()[source]
Return type:

Dict[str, Any]

is_monotone_nonnegative(expr, program=None)[source]

True if E[expr] can only grow when probability mass is added, i.e. expr is built from natural/boolean variables and non-negative literals with +, *, / (by a positive literal) and ^ (by a natural literal).

Parameters:

expr (VarExpr | BoolLitExpr | NatLitExpr | RealLitExpr | UnopExpr | BinopExpr | CategoricalExpr | SubstExpr | TickExpr | FunctionCallExpr | InferExpr | SampleExpr)

Return type:

bool

make_interval(value, kind, residual, *, monotone, probability)[source]

(lower, upper, bound, note) for a query value, see the module documentation.

Parameters:
Return type:

Tuple[Any, Any, str, str]

tighten_interval(lower, upper, bound, known)[source]

Intersects an interval with bounds known from elsewhere (None: unknown side).

Parameters:
Return type:

Tuple[Any, Any, str]

finish_query(session, query, *, monotone, probability, known=None)[source]

Fills value_float and the interval of query from the session’s bound state, intersected with known bounds (e.g. from the strategy of the loop right before the query).

Parameters:
Return type:

QueryResult

describe_distribution(dist, *, limit, kind='exact', residual=0, expectations=True)[source]
Parameters:
Return type:

Dict[str, Any]

bounds_explanation(kind, residual)[source]
Parameters:
Return type:

str

outline_program(program, source=None)[source]

Variables, parameters, loops and queries of program (for editors and forms).

Parameters:

source (str | None)

Return type:

Dict[str, Any]

type_name(typ)[source]

pGCL spelling of a declared type (nat, nat [0, 5], bool, real, …).

Return type:

str

class AnalysisResult(status='ok', error=None, program=None, input=dict(), distribution=None, error_probability=None, error_probability_float=None, bounds=dict(), queries=list(), loops=list(), steps=list(), warnings=list(), log='', timing=dict())[source]

Bases: object

Parameters:
status: str = 'ok'

ok, needs_decision, error; front ends add timeout and cancelled.

error: Dict[str, Any] | None = None
program: Dict[str, Any] | None = None
input: Dict[str, Any]
distribution: Dict[str, Any] | None = None
error_probability: str | None = None
error_probability_float: float | None = None
bounds: Dict[str, Any]
queries: List[QueryResult]
loops: List[Dict[str, Any]]
steps: List[Dict[str, Any]]
warnings: List[str]
log: str = ''
timing: Dict[str, float]
to_json()[source]
Return type:

Dict[str, Any]

build_result(session)[source]

Runs session and collects the result; analysis errors end up in the result.

Parameters:

session (AnalysisSession)

Return type:

AnalysisResult