Version: dev

observed_definitions

Stable function · Variable classification

Tier: stable · Kind: function · Topic: Variable classification

JuliaTypeScriptPythonRustGo
observed_definitionsobservedDefinitionsobserved_definitionsobserved_definitionsnot exported

Julia

observed_definitions(model::Model)
observed_definitions(model::Model) -> Dict{String,ASTExpr}

Each observed unknown mapped to its DEFINING EQUATION’s right-hand side.

An observed’s definition lives in the model’s equations array, as the bare-variable-LHS equation whose LHS names it; this is the way to read it.

An unknown that is also an ODE state is excluded (a D(y) equation defines y’s dynamics, not y itself). Where more than one equation has the same bare-variable LHS the FIRST wins, matching the reference implementation.

Source

Example (inspect)

model = doc.models["Decay"]
@assert sort(collect(keys(model.variables))) == ["N", "half_life", "lambda"]

# The two declared kinds...
@assert unknowns(model) == ["N", "half_life"]
@assert parameters(model) == ["lambda"]

# ...and what each unknown is, derived from the equations.
@assert ode_states(model) == ["N"]                 # has a D(N)/dt equation
@assert observed_unknowns(model) == ["half_life"]  # defined explicitly
@assert algebraic_unknowns(model) == String[]      # none solved implicitly

defs = observed_definitions(model)
@assert to_ascii(defs["half_life"]) == "log(2) / lambda"

From docs/api/examples/julia/documents.jl

TypeScript

function observedDefinitions(model: Model, options?: { bareOnly?: boolean }): Map<string, Expression>

The DEFINING EXPRESSION of every observed unknown: the RHS of the equation whose LHS names it, bare (y ~ f(…)) or indexed (y[i] ~ f(…)).

An observed unknown’s definition lives in the model’s equations array, not on its variable declaration; every pass that needs the definition reads it through this function.

Only the first equation for a name is recorded: a second one is an unbalanced system, which validateEquationBalance reports rather than this.

Source

Example (inspect)

const doc = loadPath(fixture('decay.esm'))
assert.deepEqual(Object.keys(doc.models ?? {}), ['Decay'])
const model = doc.models!.Decay
assert.ok(!('ref' in model)) // narrows away an unresolved `{ ref }` mount

// The document declares only `unknown` and `parameter`; everything else is derived.
assert.deepEqual(Object.keys(model.variables), ['N', 'lambda', 'half_life'])
assert.deepEqual(unknowns(model), ['N', 'half_life'])
assert.deepEqual(parameters(model), ['lambda'])

// N has a time derivative; half_life is defined by an explicit equation.
assert.deepEqual(odeStates(model), ['N'])
assert.deepEqual(observedUnknowns(model), ['half_life'])
assert.deepEqual(algebraicUnknowns(model), [])
assert.equal(isOdeState(model, 'N'), true)
assert.deepEqual(constantParameters(model), ['lambda'])
assert.equal(systemKind(model), 'ode')

// Each observed's defining expression:
const defs = observedDefinitions(model)
assert.equal(toAscii(defs.get('half_life')!), 'log(2) / lambda')

From docs/api/examples/typescript/inspect.ts

Python

observed_definitions(model: Any, bare_only: bool = False) -> dict[str, Any]

Map each observed unknown to its DEFINING equation’s RHS.

An observed unknown is one an equation defines with a bare-variable LHS; its definition lives in the model’s equations (esm-spec §6.3.1), and this function reads it from there. The FIRST defining equation wins, so classification does not depend on equation order for the set it returns.

An indexed LHS (y[i] ~ f(i), the arrayed-observed form) defines its base array, so it is credited here too: its cadence must resolve through its RHS exactly as a scalar observed’s does, and refusing to credit it would seed a const-backed geometry array CONTINUOUS and stop it folding. Pass bare_only to restrict to the strict y ~ f(…) form — see inlined_unknowns for what that distinction is for.

Source

Example (system_kind)

assert earthsci_ast.system_kind(model) == "ode"
assert earthsci_ast.is_ode_state(model, "N")
assert not earthsci_ast.is_ode_state(model, "half_life")

definitions = earthsci_ast.observed_definitions(model)
assert earthsci_ast.to_ascii(definitions["half_life"]) == "log(2) / lambda"

From docs/api/examples/python/documents.py

Rust

pub fn observed_definitions(model: &Model) -> BTreeMap<String, Expr>

Each observed unknown’s defining RHS, keyed by name.

An observed’s definition lives in the model’s equations (esm-spec §6.3.1): the equation whose left-hand side is the bare variable.

Source · Rust docs

Go

Go does not export this function.