Skip to content

Gaia Lang Public Surface API

Status: Generated from current Python docstrings and type hints.

Top-level gaia.engine.lang imports exposed to package authors. More focused pages below split the DSL, runtime models, formula AST, compiler, and reference helpers.

gaia.engine.lang

Gaia Lang — Python DSL for knowledge authoring.

BoolExpr dataclass

BoolExpr(op: ComparisonOp, left: Any, right: Any)

Boolean proposition over Distribution objects.

Created by Distribution comparison operators (k > 1e-3, y == baseline + slope * x). claim(content, expr) accepts a BoolExpr as the second argument and lowers it to claim metadata so the compiler can compute the resulting prior via the underlying distribution's CDF (for inequality predicates). Equality / equation predicates are preserved in metadata with author/default priors; constraint lowering is future work.

The :meth:__bool__ override raises so accidental Python control-flow use (if k > 1e-3: ...) surfaces immediately rather than silently always evaluating to True (the dataclass would otherwise be truthy).

DerivedDistribution dataclass

DerivedDistribution(op: ArithmeticOp, left: Any, right: Any)

Arithmetic combination of distributions / scalars (e.g. baseline + slope * x).

Used as the right-hand side of an :class:Equation proposition. Carries no runtime sampling logic — it is a syntactic placeholder retained in equation metadata for audit and future constraint lowering.

Constants (Python int / float / Quantity) and other DerivedDistributions may appear on either operand position.

ArithOp dataclass

ArithOp(op: str, left: Any, right: Any)

An arithmetic operation between two Terms.

ClaimAtom dataclass

ClaimAtom(claim: Claim)

A reference to another Claim's truth — the bridge from formula land to claim graph.

Constant dataclass

Constant(value: Any, primitive: PrimitiveType)

A primitive literal value, validated against its declared PrimitiveType.

Equals dataclass

Equals(left: Any, right: Any)

Term equality formula.

Formula

Bases: Protocol

Marker protocol — a truth-valued AST node.

FunctionApp dataclass

FunctionApp(symbol: FunctionSymbol, args: tuple[Any, ...])

Application of a FunctionSymbol to a tuple of Term arguments.

FunctionSymbol dataclass

FunctionSymbol(name: str, arg_domains: tuple[PrimitiveType | Domain, ...], result_domain: PrimitiveType | Domain)

Declaration of a user function symbol like E: Particle → Real.

Greater dataclass

Greater(left: Any, right: Any)

Greater-than relation over Term operands.

GreaterEqual dataclass

GreaterEqual(left: Any, right: Any)

Greater-than-or-equal relation over Term operands.

Iff dataclass

Iff(left: Any, right: Any)

Logical equivalence between two Formula operands.

Implies dataclass

Implies(antecedent: Any, consequent: Any)

Logical implication from antecedent Formula to consequent Formula.

Land dataclass

Land(operands: tuple[Any, ...])

Logical conjunction over two or more Formula operands.

Less dataclass

Less(left: Any, right: Any)

Less-than relation over Term operands.

LessEqual dataclass

LessEqual(left: Any, right: Any)

Less-than-or-equal relation over Term operands.

Lnot dataclass

Lnot(operand: Any)

Logical negation of a Formula operand.

Lor dataclass

Lor(operands: tuple[Any, ...])

Logical disjunction over two or more Formula operands.

NotEquals dataclass

NotEquals(left: Any, right: Any)

Term inequality formula.

PredicateSymbol dataclass

PredicateSymbol(name: str, arg_domains: tuple[PrimitiveType | Domain, ...])

Declaration of a user predicate symbol like Stable: Particle → Bool.

Term

Bases: Protocol

Marker protocol. A Term is a value-bearing expression node.

UserPredicate dataclass

UserPredicate(symbol: PredicateSymbol, args: tuple[Any, ...])

Application of a user-declared PredicateSymbol to typed Term arguments.

PrimitiveType

PrimitiveType(name: str, accept: Callable[[object], bool])

A built-in typed sort. Construction is sealed once the module finishes loading.

Create a primitive type token before the module is sealed.

Source code in gaia/engine/lang/formula/primitives.py
20
21
22
23
24
25
26
27
def __init__(self, name: str, accept: Callable[[object], bool]) -> None:
    """Create a primitive type token before the module is sealed."""
    if _SEALED:
        raise TypeError(
            "PrimitiveType is sealed. Use the four built-ins: Nat, Real, Probability, Bool."
        )
    self.name = name
    self._accept = accept

accepts

accepts(value: object) -> bool

Return whether value belongs to this primitive type.

Source code in gaia/engine/lang/formula/primitives.py
29
30
31
def accepts(self, value: object) -> bool:
    """Return whether ``value`` belongs to this primitive type."""
    return self._accept(value)

Associate dataclass

Associate(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), helper: Claim | None = None, a: Claim | None = None, b: Claim | None = None, p_a_given_b: float = 0.5, p_b_given_a: float = 0.5, pattern: str | None = None)

Bases: Relation

Symmetric probabilistic association between two Claims.

CandidateRelation dataclass

CandidateRelation(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), claims: tuple[Claim, ...] = (), pattern: str | None = None, status: str = 'hypothesis')

Bases: Scaffold

Marks a hypothesized relation that has not been formalized yet.

a property

a: Claim | None

Compatibility view for older binary callers.

b property

b: Claim | None

Compatibility view for older binary callers.

proposed property

proposed: str | None

Compatibility view for older proposed-pattern callers.

Claim dataclass

Claim(content: str | None = None, *, prior: float | None = None, from_actions: list[Any] | None = None, formula: Any = None, kind: ClaimKind = ClaimKind.GENERAL, **kwargs: Any)

Bases: Knowledge

Proposition with prior. Participates in BP.

Create a probabilistic claim node.

Source code in gaia/engine/lang/runtime/knowledge.py
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
def __init__(
    self,
    content: str | None = None,
    *,
    prior: float | None = None,
    from_actions: list[Any] | None = None,
    formula: Any = None,
    kind: ClaimKind = ClaimKind.GENERAL,
    **kwargs: Any,
) -> None:
    """Create a probabilistic claim node."""
    _validate_formula_and_kind(formula, kind)
    param_fields = getattr(self.__class__, "_param_fields", {})
    param_values, knowledge_kwargs = _split_param_kwargs(kwargs, param_fields)
    params = _parameter_entries(param_fields, param_values)

    template = self.__class__.__doc__ or ""
    content = _render_templated_content(
        content,
        template=template,
        param_fields=param_fields,
        param_values=param_values,
        knowledge_kwargs=knowledge_kwargs,
    )

    for name, val in param_values.items():
        object.__setattr__(self, name, val)

    super().__init__(
        content=content or "",
        type="claim",
        parameters=params or knowledge_kwargs.pop("parameters", []),
        **knowledge_kwargs,
    )
    self.prior = prior
    self.from_actions = list(from_actions or [])
    self.formula = formula
    self.kind = kind

ClaimKind

Bases: Enum

Shape discriminator for the structured-content of a Claim (spec §4.2).

GENERAL — default; formula optional, no structural commitments PARAMETER — asserts a Variable takes a specific value (Equals(var, const)) QUANTIFIED — top-level quantifier (Forall/Exists) in formula

NOT a "role" (hypothesis/prediction/observation-as-evidence) — those live on action graph nodes. Observation is an Observe action, not a Claim kind. NOT helper-claim metadata.

Compose dataclass

Compose(name: str = '', version: str = '', inputs: tuple[Knowledge | str, ...] = (), actions: tuple[Action | str, ...] = (), conclusion: Claim | None = None)

Bases: Action

Action-level composition of child actions into a reviewable DAG.

structure_hash

structure_hash(input_refs: list[str], action_refs: list[str], conclusion_ref: str, warrant_refs: list[str], background_refs: list[str] | None = None) -> str

Hash the canonical compose payload used for the IR compose ID.

Source code in gaia/engine/lang/runtime/action.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
def structure_hash(
    self,
    input_refs: list[str],
    action_refs: list[str],
    conclusion_ref: str,
    warrant_refs: list[str],
    background_refs: list[str] | None = None,
) -> str:
    """Hash the canonical compose payload used for the IR compose ID."""
    payload = {
        "name": self.name,
        "version": self.version,
        "inputs": sorted(input_refs),
        "background": sorted(background_refs or []),
        "actions": list(action_refs),
        "conclusion": conclusion_ref,
        "warrants": sorted(warrant_refs),
    }
    canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
    return hashlib.sha256(canonical.encode()).hexdigest()[:16]

Compute dataclass

Compute(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), conclusion: Claim | None = None, given: tuple[Claim, ...] = (), fn: Callable[..., Any] | None = None, code_hash: str | None = None)

Bases: Support

Deterministic code execution.

Contradict dataclass

Contradict(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), a: Claim | None = None, b: Claim | None = None, helper: Claim | None = None)

Bases: Structural

Declares two Claims contradictory.

Decompose dataclass

Decompose(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), whole: Claim | None = None, parts: tuple[Claim, ...] = (), formula: Any = None)

Bases: Reasoning

Declares a whole Claim equivalent to a formula over atomic Claims.

DependsOn dataclass

DependsOn(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), conclusion: Claim | None = None, given: tuple[Claim, ...] = ())

Bases: Scaffold

Marks unformalized dependencies for a conclusion.

Derive dataclass

Derive(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), conclusion: Claim | None = None, given: tuple[Claim, ...] = ())

Bases: Support

Logical derivation.

Distribution dataclass

Distribution(content: str, *, impl: _BaseDistribution, format: str = 'markdown', **kwargs: Any)

Bases: Knowledge

Knowledge-wrapped continuous quantity with a probability distribution.

Use the family-specific factories (:func:Normal, :func:LogNormal, :func:Beta, etc.) rather than constructing this directly — they wrap the matching gaia.engine.bayes.distributions._BaseDistribution subclass into a Distribution carrying a content string + identity.

The wrapped computational object is available as .impl and exposes logpdf / logpmf / cdf / support / model_dump via thin delegating properties on this class.

Create a Knowledge-wrapped distribution.

Parameters:

Name Type Description Default
content str

Human-readable description of what this quantity is.

required
impl _BaseDistribution

A _BaseDistribution subclass instance (Normal, Beta, …) that provides the computational backend.

required
format str

Content format (markdown by default).

'markdown'
**kwargs Any

Standard :class:Knowledge keyword arguments (title, label, metadata, provenance, …).

{}
Source code in gaia/engine/lang/runtime/distribution.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def __init__(
    self,
    content: str,
    *,
    impl: _BaseDistribution,
    format: str = "markdown",
    **kwargs: Any,
) -> None:
    """Create a Knowledge-wrapped distribution.

    Args:
        content: Human-readable description of what this quantity is.
        impl: A ``_BaseDistribution`` subclass instance (Normal, Beta, …)
            that provides the computational backend.
        format: Content format (markdown by default).
        **kwargs: Standard :class:`Knowledge` keyword arguments
            (``title``, ``label``, ``metadata``, ``provenance``, …).
    """
    from gaia.engine.bayes.distributions.base import _BaseDistribution

    if not isinstance(impl, _BaseDistribution):
        raise TypeError(
            "Distribution(impl=...) must be a _BaseDistribution instance "
            "from gaia.engine.bayes.distributions; got "
            f"{type(impl).__name__}. Use the family factories (Normal, "
            "LogNormal, Beta, ...) instead of constructing Distribution "
            "directly."
        )
    super().__init__(content=content, type="distribution", format=format, **kwargs)
    self._impl = impl

impl property

impl: _BaseDistribution

Return the wrapped computational distribution object.

kind property

kind: str

Distribution family identifier ("normal", "beta", ...).

params property

params: dict[str, Any]

Return the distribution parameter dictionary.

logpdf

logpdf(x: float) -> float

Evaluate the log probability density at x (continuous).

Source code in gaia/engine/lang/runtime/distribution.py
239
240
241
def logpdf(self, x: float) -> float:
    """Evaluate the log probability density at ``x`` (continuous)."""
    return cast("_DistImpl", self._impl).logpdf(x)

logpmf

logpmf(k: int) -> float

Evaluate the log probability mass at k (discrete).

Source code in gaia/engine/lang/runtime/distribution.py
243
244
245
def logpmf(self, k: int) -> float:
    """Evaluate the log probability mass at ``k`` (discrete)."""
    return cast("_DistImpl", self._impl).logpmf(k)

support

support() -> tuple[float, float]

Return the inclusive support bounds of the distribution.

Source code in gaia/engine/lang/runtime/distribution.py
247
248
249
def support(self) -> tuple[float, float]:
    """Return the inclusive support bounds of the distribution."""
    return cast("_DistImpl", self._impl).support()

cdf

cdf(x: float) -> float

Cumulative distribution function P(X <= x).

Used at compile time to compute the prior of a predicate claim (P(k > c) = 1 - dist.cdf(c)). Lazy import of scipy keeps this out of the cold import path.

Source code in gaia/engine/lang/runtime/distribution.py
251
252
253
254
255
256
257
258
259
260
261
262
def cdf(self, x: float) -> float:
    """Cumulative distribution function P(X <= x).

    Used at compile time to compute the prior of a predicate claim
    (``P(k > c) = 1 - dist.cdf(c)``). Lazy import of scipy keeps this
    out of the cold import path.
    """
    from gaia.engine.bayes.adapters.scipy_backend import _to_scipy_dist

    impl = cast("_BaseDistribution", self._impl)
    resolved = impl._resolved_params()
    return float(_to_scipy_dist(impl.kind, resolved).cdf(x))

model_dump

model_dump() -> dict[str, Any]

Return the JSON-serialisable distribution literal payload.

Source code in gaia/engine/lang/runtime/distribution.py
264
265
266
def model_dump(self) -> dict[str, Any]:
    """Return the JSON-serialisable distribution literal payload."""
    return cast("_DistImpl", self._impl).model_dump()

Domain dataclass

Domain(content: str, *, members: list[Any], format: str = 'markdown', **kwargs: Any)

Bases: Knowledge

A user-declared, finite, enumerable typed sort.

Subclasses Knowledge so it carries identity, provenance, and metadata. Lang-only: does NOT enter the package's IR-bound knowledge map.

Create a finite enumerable authoring domain.

Source code in gaia/engine/lang/runtime/domain.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def __init__(
    self,
    content: str,
    *,
    members: list[Any],
    format: str = "markdown",
    **kwargs: Any,
) -> None:
    """Create a finite enumerable authoring domain."""
    if not isinstance(members, list):
        raise TypeError("members must be a list")
    if len(members) == 0:
        raise ValueError("members must be a non-empty list")
    super().__init__(content=content, type="domain", format=format, **kwargs)
    self.members = list(members)

Equal dataclass

Equal(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), a: Claim | None = None, b: Claim | None = None, helper: Claim | None = None)

Bases: Structural

Declares two Claims equivalent.

Exclusive dataclass

Exclusive(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), a: Claim | None = None, b: Claim | None = None, helper: Claim | None = None)

Bases: Structural

Declares two Claims form a closed binary partition.

Infer dataclass

Infer(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), helper: Claim | None = None, hypothesis: Claim | None = None, evidence: Claim | None = None, given: tuple[Claim, ...] = (), p_e_given_h: float | Claim = 0.5, p_e_given_not_h: float | Claim | None = 0.5, p_e_given_not_h_defaulted: bool = False)

Bases: Directed

Bayesian inference: P(E|H) update.

Knowledge dataclass

Knowledge(content: str, format: str = 'markdown', type: str = 'knowledge', title: str | None = None, background: list[Knowledge] = list(), parameters: list[dict[str, Any]] = list(), provenance: list[dict[str, str]] = list(), metadata: dict[str, Any] = dict(), label: str | None = None, strategy: Any | None = None)

Base knowledge node. Plain text plus metadata.

MaterializationLink(scaffold: Scaffold, by: tuple[GaiaGraph, ...], label: str | None = None, rationale: str = '', metadata: dict[str, Any] = dict())

Bookkeeping link from scaffold to the formal graph records that handle it.

Note dataclass

Note(content: str, *, format: str = 'markdown', **kwargs: Any)

Bases: Knowledge

Non-probabilistic contextual material. Does not enter BP.

Create a non-probabilistic note.

Source code in gaia/engine/lang/runtime/knowledge.py
66
67
68
69
70
def __init__(self, content: str, *, format: str = "markdown", **kwargs: Any) -> None:
    """Create a non-probabilistic note."""
    if "prior" in kwargs:
        raise TypeError("Note cannot have a prior.")
    super().__init__(content=content, type="note", format=format, **kwargs)

Observe dataclass

Observe(label: str | None = None, rationale: str = '', background: list[Knowledge] = list(), metadata: dict[str, Any] = dict(), warrants: list[Claim] = list(), conclusion: Claim | None = None, given: tuple[Claim, ...] = ())

Bases: Support

Empirical observation or measurement.

Question dataclass

Question(content: str, **kwargs: Any)

Bases: Knowledge

Open inquiry. Does not enter BP.

Create a non-probabilistic question.

Source code in gaia/engine/lang/runtime/knowledge.py
353
354
355
356
357
358
359
def __init__(self, content: str, **kwargs: Any) -> None:
    """Create a non-probabilistic question."""
    if "prior" in kwargs:
        raise TypeError("Question cannot have a prior.")
    targets = kwargs.pop("targets", [])
    super().__init__(content=content, type="question", **kwargs)
    self.targets = list(targets)

RoleOccurrence dataclass

RoleOccurrence(claim: Claim, role: str, action: Action, action_type: str, action_label: str | None = None, path: tuple[str, ...] = (), source: str = 'explicit_field')

A claim role at a specific occurrence in an authored action.

Variable dataclass

Variable(*, symbol: str, domain: PrimitiveType | Domain, value: Any | None = None, unit: str | None = None, content: str | None = None, format: str = 'markdown', **kwargs: Any)

Bases: Knowledge

A typed term referenceable by formulas, models, and actions.

Subclasses Knowledge for identity, provenance, metadata. Carries a symbol used in formulas, a domain (PrimitiveType or user-declared Domain), and an optional bound value. Binding semantics (CONSTANT / FREE / BOUND_BY_CLAIM) are inferred by Milestone B's compiler; this class stores only authored data.

Lang-only: does NOT enter the package's IR-bound knowledge map (spec §2.4).

Create a typed authoring variable.

Source code in gaia/engine/lang/runtime/variable.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def __init__(
    self,
    *,
    symbol: str,
    domain: PrimitiveType | Domain,
    value: Any | None = None,
    unit: str | None = None,
    content: str | None = None,
    format: str = "markdown",
    **kwargs: Any,
) -> None:
    """Create a typed authoring variable."""
    if not isinstance(symbol, str) or not symbol:
        raise TypeError("symbol must be a non-empty string")
    if not isinstance(domain, (PrimitiveType, Domain)):
        raise TypeError("domain must be a PrimitiveType or a Domain")

    if value is not None:
        _validate_value(value, domain)

    canonical_unit_value: str | None = None
    if unit is not None:
        from gaia.unit import canonical_unit

        canonical_unit_value = canonical_unit(unit)

    if content is None:
        content = _default_content(symbol, domain, value, canonical_unit_value)

    super().__init__(content=content, type="variable", format=format, **kwargs)
    self.symbol = symbol
    self.domain = domain
    self.value = value
    self.unit = canonical_unit_value

artifact

artifact(*, kind: str, source: str | None = None, locator: str | None = None, path: str | None = None, caption: str | None = None, description: str | None = None, media_type: str | None = None, content: str | None = None, title: str | None = None) -> Note

Create a note carrying structured artifact metadata.

Source code in gaia/engine/lang/dsl/artifacts.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def artifact(
    *,
    kind: str,
    source: str | None = None,
    locator: str | None = None,
    path: str | None = None,
    caption: str | None = None,
    description: str | None = None,
    media_type: str | None = None,
    content: str | None = None,
    title: str | None = None,
) -> Note:
    """Create a note carrying structured artifact metadata."""
    artifact_meta = build_artifact_metadata(
        kind=kind,
        source=source,
        locator=locator,
        path=path,
        caption=caption,
        description=description,
        media_type=media_type,
    )
    note_content = content or caption or description or locator or path or source or kind
    return note(note_content, title=title, metadata={"gaia": {"artifact": artifact_meta}})

associate

associate(a: Any, b: Any, *, p_a_given_b: float, p_b_given_a: float, pattern: str | None = None, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim

Declare a symmetric probabilistic association. Returns an association helper Claim.

a and b may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/associate_verb.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def associate(
    a: Any,
    b: Any,
    *,
    p_a_given_b: float,
    p_b_given_a: float,
    pattern: str | None = None,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Declare a symmetric probabilistic association. Returns an association helper Claim.

    ``a`` and ``b`` may be any Boolean-valued expression (``Claim``,
    ``ClaimAtom``, Formula node, or ``BoolExpr``); non-``Claim`` inputs are
    lifted to helper Claims at the verb boundary per RFC #703.
    """
    a = _lift_to_claim(a, verb="associate", position="first argument")
    b = _lift_to_claim(b, verb="associate", position="second argument")
    _validate_pattern(pattern, p_a_given_b=p_a_given_b, p_b_given_a=p_b_given_a)

    helper = Claim(
        f"{_claim_ref(a)} and {_claim_ref(b)} are statistically associated.",
        metadata={
            "generated": True,
            "helper_kind": "association",
            "review": True,
            "relation": {
                "type": "associate",
                "a": a,
                "b": b,
                "p_a_given_b": p_a_given_b,
                "p_b_given_a": p_b_given_a,
                "pattern": pattern,
            },
        },
    )
    action = AssociateAction(
        label=label,
        rationale=rationale,
        background=list(background or []),
        a=a,
        b=b,
        p_a_given_b=p_a_given_b,
        p_b_given_a=p_b_given_a,
        pattern=pattern,
        helper=helper,
    )
    validate_no_self_warrant(action, helper)
    attach_reasoning(helper, action)
    return helper

candidate_relation

candidate_relation(*, claims: list[Any] | tuple[Any, ...], pattern: str | None = None, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None, metadata: dict[str, Any] | None = None) -> CandidateRelation

Record a hypothesized relation without triggering formal semantics.

Every entry of claims may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/scaffold.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def candidate_relation(
    *,
    claims: list[Any] | tuple[Any, ...],
    pattern: str | None = None,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
    metadata: dict[str, Any] | None = None,
) -> CandidateRelation:
    """Record a hypothesized relation without triggering formal semantics.

    Every entry of ``claims`` may be any Boolean-valued expression
    (``Claim``, ``ClaimAtom``, Formula node, or ``BoolExpr``);
    non-``Claim`` inputs are lifted to helper Claims at the verb boundary
    per RFC #703.
    """
    claim_tuple = tuple(
        _lift_to_claim(item, verb="candidate_relation", position=f"claims[{i}]")
        for i, item in enumerate(claims)
    )
    if len(claim_tuple) < 2:
        raise ValueError("candidate_relation requires at least two Claims")
    if pattern is not None and pattern not in _CANDIDATE_RELATION_KINDS:
        allowed = ", ".join(sorted(_CANDIDATE_RELATION_KINDS))
        raise ValueError(f"candidate_relation pattern must be one of: {allowed}")
    if pattern == "contradict" and len(claim_tuple) != 2:
        raise ValueError('candidate_relation(pattern="contradict") requires exactly two Claims')
    return CandidateRelation(
        label=label,
        rationale=rationale,
        background=list(background or []),
        metadata=dict(metadata or {}),
        claims=claim_tuple,
        pattern=pattern,
    )

claim

claim(content: str, proposition: BoolExpr | None = None, *, title: str | None = None, format: str = 'markdown', background: list[Knowledge] | None = None, parameters: list[dict[str, Any]] | None = None, provenance: list[dict[str, str]] | None = None, prior: float | None = None, formula: Any = None, kind: ClaimKind = ClaimKind.GENERAL, tolerance: float | None = None, **metadata: Any) -> Claim

Declare a scientific assertion.

Three authoring shapes:

  1. Prose claimclaim("Heliocentric model is correct.", prior=0.8). The proposition is conveyed in natural language. The optional prior keyword is a low-priority shortcut routed through register_prior() with source_id="claim_inline".
  2. Predicate claimclaim("Reaction is fast", k > 1e-2). The second positional argument is a :class:BoolExpr produced by comparing a :class:Distribution against a constant. The compiler registers a CDF-derived prior record for inequality predicates. See :class:gaia.engine.lang.Distribution for how to declare the underlying continuous quantity.
  3. Formula claimclaim(content, formula=Forall(...)) for the predicate-logic surface (unchanged from v0.5).

The tolerance keyword applies only when proposition is an equation (lhs == rhs). PR1 stores equation metadata and a neutral default prior; equation constraint lowering is deferred.

Source code in gaia/engine/lang/dsl/knowledge.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
def claim(
    content: str,
    proposition: BoolExpr | None = None,
    *,
    title: str | None = None,
    format: str = "markdown",
    background: list[Knowledge] | None = None,
    parameters: list[dict[str, Any]] | None = None,
    provenance: list[dict[str, str]] | None = None,
    prior: float | None = None,
    formula: Any = None,
    kind: ClaimKind = ClaimKind.GENERAL,
    tolerance: float | None = None,
    **metadata: Any,
) -> Claim:
    """Declare a scientific assertion.

    Three authoring shapes:

    1. **Prose claim** — ``claim("Heliocentric model is correct.", prior=0.8)``.
       The proposition is conveyed in natural language. The optional ``prior``
       keyword is a low-priority shortcut routed through ``register_prior()``
       with ``source_id="claim_inline"``.
    2. **Predicate claim** — ``claim("Reaction is fast", k > 1e-2)``. The
       second positional argument is a :class:`BoolExpr` produced by
       comparing a :class:`Distribution` against a constant. The compiler
       registers a CDF-derived prior record for inequality predicates.
       See :class:`gaia.engine.lang.Distribution` for how to declare the
       underlying continuous quantity.
    3. **Formula claim** — ``claim(content, formula=Forall(...))`` for the
       predicate-logic surface (unchanged from v0.5).

    The ``tolerance`` keyword applies only when ``proposition`` is an equation
    (``lhs == rhs``). PR1 stores equation metadata and a neutral default prior;
    equation constraint lowering is deferred.
    """
    raw_metadata = _flatten_metadata(metadata)
    if proposition is not None:
        if not isinstance(proposition, BoolExpr):
            raise TypeError(
                "claim() second positional argument must be a BoolExpr produced "
                "by comparing a Distribution against another value (e.g. "
                "k > 1e-2). Got "
                f"{type(proposition).__name__}. For prose claims, omit the "
                "second argument; for predicate-logic claims, use the "
                "`formula=` keyword."
            )
        # The full lowering of predicate / equation propositions to claim
        # priors happens in `gaia.engine.lang.compiler.compile`; here we just stash
        # the BoolExpr on metadata for the compiler to read.
        if "predicate" in raw_metadata or "equation" in raw_metadata:
            raise TypeError(
                "claim() received both a proposition argument and a manually "
                "set metadata['predicate'] / metadata['equation'] entry — pick "
                "one."
            )
        slot = "equation" if proposition.op in {"==", "!="} else "predicate"
        raw_metadata = dict(raw_metadata)
        raw_metadata[slot] = proposition
        if tolerance is not None:
            if slot != "equation":
                raise TypeError(
                    "claim(tolerance=...) only applies to equation propositions "
                    "(``y == baseline + slope * x``); for inequality predicates the "
                    "prior is exact via CDF integration."
                )
            if not isinstance(tolerance, (int, float)) or float(tolerance) <= 0.0:
                raise ValueError(
                    f"claim(tolerance=...) must be a positive number, got {tolerance!r}."
                )
            raw_metadata["equation_tolerance"] = float(tolerance)
    elif tolerance is not None:
        raise TypeError(
            "claim(tolerance=...) requires a proposition (equation BoolExpr). "
            "It does nothing on a prose or formula claim."
        )
    c = Claim(
        content=content.strip(),
        format=format,
        title=title,
        background=background or [],
        parameters=parameters or [],
        provenance=provenance or [],
        prior=None,
        formula=formula,
        kind=kind,
        metadata=raw_metadata,
    )
    if prior is not None:
        # Route through register_prior so the inline value participates in the
        # same multi-source PriorRecord pipeline as everything else. The
        # "claim_inline" shortcut is intentionally low priority, below
        # generated continuous-inference priors and documented register_prior()
        # calls.
        from gaia.engine.lang.dsl.register_prior import register_prior

        register_prior(
            c,
            prior,
            source_id="claim_inline",
            justification="(inline default declared at claim() call site)",
        )
    return c

compose

compose(*, name: str, version: str, background: list[Knowledge] | None = None, warrants: list[Claim] | None = None, rationale: str = '', label: str | None = None) -> Callable[[Callable[..., Claim]], Callable[..., Claim]]

Decorate a function as a Gaia action composition template.

Source code in gaia/engine/lang/runtime/composition.py
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def compose(
    *,
    name: str,
    version: str,
    background: list[Knowledge] | None = None,
    warrants: list[Claim] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Callable[[Callable[..., Claim]], Callable[..., Claim]]:
    """Decorate a function as a Gaia action composition template."""

    def decorator(fn: Callable[..., Claim]) -> Callable[..., Claim]:
        @wraps(fn)
        def wrapper(*args: Any, **kwargs: Any) -> Claim:
            scope = _CompositionScope(name, version)
            token = _current_composition_scope.set(scope)
            try:
                result = fn(*args, **kwargs)
            finally:
                _current_composition_scope.reset(token)
            if not isinstance(result, Claim):
                raise TypeError("@compose functions must return a Claim object")

            compose_background = list(background or [])
            compose_action = Compose(
                label=label,
                rationale=rationale,
                background=compose_background,
                warrants=list(warrants or []),
                name=name,
                version=version,
                inputs=_infer_inputs(
                    args=args,
                    kwargs=kwargs,
                    actions=scope.captured_actions,
                    background=compose_background,
                ),
                actions=tuple(scope.captured_actions),
                conclusion=result,
            )
            validate_no_self_warrant(compose_action, result)
            attach_reasoning(result, compose_action)
            return result

        return wrapper

    return decorator

compute

compute(conclusion_type: type[Claim] | Callable[..., Any], *, fn: Callable[..., Any] | None = None, given: Claim | tuple[Claim, ...] | list[Claim] | None = (), background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim | Callable[..., Claim]

Deterministic computation.

Used either as compute(ResultClaim, fn=..., given=...) or as @compute.

Source code in gaia/engine/lang/dsl/support.py
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
def compute(
    conclusion_type: type[Claim] | Callable[..., Any],
    *,
    fn: Callable[..., Any] | None = None,
    given: Claim | tuple[Claim, ...] | list[Claim] | None = (),
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim | Callable[..., Claim]:
    """Deterministic computation.

    Used either as ``compute(ResultClaim, fn=..., given=...)`` or as ``@compute``.
    """
    if callable(conclusion_type) and not inspect.isclass(conclusion_type) and fn is None:
        wrapped_fn = conclusion_type
        # ``eval_str=True`` resolves PEP-563 string annotations so wrappers
        # written in modules with ``from __future__ import annotations`` (the
        # default for most modern Python projects) still produce a real
        # type object for the return annotation rather than the bare string
        # ``"PrecomputedLikelihoods"``. Required for downstream
        # ``isinstance(result_value, return_type)`` to work in
        # ``_wrap_result`` — passing a string there raises TypeError.
        sig = inspect.signature(wrapped_fn, eval_str=True)
        return_type = sig.return_annotation
        if return_type is inspect.Signature.empty:
            raise TypeError("@compute requires a Claim return annotation")

        @wraps(wrapped_fn)
        def wrapper(*args: Any, **kwargs: Any) -> Claim:
            result_value = wrapped_fn(*args, **kwargs)
            conclusion = _wrap_result(return_type, result_value)
            given_tuple = _bound_given(sig, *args, **kwargs)
            action_rationale = inspect.getdoc(wrapped_fn) or ""
            warrant = _implication_warrant(
                "compute",
                given=given_tuple,
                conclusion=conclusion,
                rationale=action_rationale,
            )
            action = Compute(
                label=label,
                rationale=action_rationale,
                background=list(background or []),
                warrants=[warrant],
                conclusion=conclusion,
                given=given_tuple,
                fn=wrapped_fn,
            )
            validate_no_self_warrant(action, conclusion)
            attach_reasoning(conclusion, action)
            return conclusion

        return wrapper

    if not inspect.isclass(conclusion_type) or not issubclass(conclusion_type, Claim):
        raise TypeError("compute() first argument must be a Claim subclass or decorated function")
    return _compute_call(
        conclusion_type,
        fn=fn,
        given=given,
        background=background,
        rationale=rationale,
        label=label,
    )

contradict

contradict(a: Any, b: Any, *, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim

Declare two Claims contradictory. Returns a contradiction helper Claim.

a and b may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/relate.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def contradict(
    a: Any,
    b: Any,
    *,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Declare two Claims contradictory. Returns a contradiction helper Claim.

    ``a`` and ``b`` may be any Boolean-valued expression (``Claim``,
    ``ClaimAtom``, Formula node, or ``BoolExpr``); non-``Claim`` inputs are
    lifted to helper Claims at the verb boundary per RFC #703.
    """
    a = _lift_to_claim(a, verb="contradict", position="first argument")
    b = _lift_to_claim(b, verb="contradict", position="second argument")
    helper = Claim(
        f"{_claim_ref(a)} and {_claim_ref(b)} contradict.",
        metadata={"generated": True, "helper_kind": "contradiction_result", "review": True},
    )
    action = Contradict(
        label=label,
        rationale=rationale,
        background=list(background or []),
        a=a,
        b=b,
        helper=helper,
    )
    validate_no_self_warrant(action, helper)
    attach_reasoning(helper, action)
    return helper

depends_on

depends_on(conclusion: Any, *, given: Any, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None, metadata: dict[str, Any] | None = None) -> DependsOn

Record unformalized load-bearing dependencies for a Claim.

conclusion and every entry of given may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/scaffold.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def depends_on(
    conclusion: Any,
    *,
    given: Any,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
    metadata: dict[str, Any] | None = None,
) -> DependsOn:
    """Record unformalized load-bearing dependencies for a Claim.

    ``conclusion`` and every entry of ``given`` may be any Boolean-valued
    expression (``Claim``, ``ClaimAtom``, Formula node, or ``BoolExpr``);
    non-``Claim`` inputs are lifted to helper Claims at the verb boundary
    per RFC #703.
    """
    conclusion = _lift_to_claim(conclusion, verb="depends_on", position="conclusion")
    given_tuple = tuple(
        _lift_to_claim(item, verb="depends_on", position=f"given[{i}]")
        for i, item in enumerate(_as_claim_tuple(given))
    )
    if not given_tuple:
        raise ValueError("depends_on requires at least one given Claim")
    return DependsOn(
        label=label,
        rationale=rationale,
        background=list(background or []),
        metadata=dict(metadata or {}),
        conclusion=conclusion,
        given=given_tuple,
    )

derive

derive(conclusion: Any, *, given: Any = (), background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim

Logical derivation. Returns the conclusion Claim.

conclusion may be a Claim, a str (which creates a fresh Claim from the content), or any Boolean-valued expression (ClaimAtom / Formula / BoolExpr) that lifts to a helper Claim at the verb boundary per RFC #703.

Every entry of given is similarly lifted: a Boolean-valued expression becomes a helper Claim; non-Claim non-Boolean-valued values raise an educational :class:TypeError.

Source code in gaia/engine/lang/dsl/support.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def derive(
    conclusion: Any,
    *,
    given: Any = (),
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Logical derivation. Returns the conclusion Claim.

    ``conclusion`` may be a ``Claim``, a ``str`` (which creates a fresh
    Claim from the content), or any Boolean-valued expression
    (``ClaimAtom`` / Formula / ``BoolExpr``) that lifts to a helper Claim
    at the verb boundary per RFC #703.

    Every entry of ``given`` is similarly lifted: a Boolean-valued
    expression becomes a helper Claim; non-Claim non-Boolean-valued values
    raise an educational :class:`TypeError`.
    """
    if isinstance(conclusion, str):
        conclusion = Claim(conclusion)
    else:
        conclusion = _lift_to_claim(conclusion, verb="derive", position="conclusion")
    assert isinstance(conclusion, Claim)  # narrow Any back to Claim for mypy
    given_tuple = tuple(
        _lift_to_claim(g, verb="derive", position=f"given[{i}]")
        for i, g in enumerate(_as_given_tuple(given))
    )
    warrant = _implication_warrant(
        "derive",
        given=given_tuple,
        conclusion=conclusion,
        rationale=rationale,
    )
    action = Derive(
        label=label,
        rationale=rationale,
        background=list(background or []),
        warrants=[warrant],
        conclusion=conclusion,
        given=given_tuple,
    )
    validate_no_self_warrant(action, conclusion)
    attach_reasoning(conclusion, action)
    return conclusion

equal

equal(a: Any, b: Any, *, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim

Declare two Claims equivalent. Returns an equivalence helper Claim.

a and b may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/relate.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def equal(
    a: Any,
    b: Any,
    *,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Declare two Claims equivalent. Returns an equivalence helper Claim.

    ``a`` and ``b`` may be any Boolean-valued expression (``Claim``,
    ``ClaimAtom``, Formula node, or ``BoolExpr``); non-``Claim`` inputs are
    lifted to helper Claims at the verb boundary per RFC #703.
    """
    a = _lift_to_claim(a, verb="equal", position="first argument")
    b = _lift_to_claim(b, verb="equal", position="second argument")
    helper = Claim(
        f"{_claim_ref(a)} and {_claim_ref(b)} are equivalent.",
        metadata={"generated": True, "helper_kind": "equivalence_result", "review": True},
    )
    action = Equal(
        label=label,
        rationale=rationale,
        background=list(background or []),
        a=a,
        b=b,
        helper=helper,
    )
    validate_no_self_warrant(action, helper)
    attach_reasoning(helper, action)
    return helper

equals

equals(left: Any, right: Any) -> Equals

Create an equality formula.

Source code in gaia/engine/lang/dsl/formula.py
53
54
55
def equals(left: Any, right: Any) -> Equals:
    """Create an equality formula."""
    return Equals(left=left, right=right)

exclusive

exclusive(a: Any, b: Any, *, background: list[Knowledge] | None = None, rationale: str = '', label: str | None = None) -> Claim

Declare two Claims as a closed binary partition. Returns an XOR helper Claim.

a and b may be any Boolean-valued expression (Claim, ClaimAtom, Formula node, or BoolExpr); non-Claim inputs are lifted to helper Claims at the verb boundary per RFC #703.

Source code in gaia/engine/lang/dsl/relate.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def exclusive(
    a: Any,
    b: Any,
    *,
    background: list[Knowledge] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Declare two Claims as a closed binary partition. Returns an XOR helper Claim.

    ``a`` and ``b`` may be any Boolean-valued expression (``Claim``,
    ``ClaimAtom``, Formula node, or ``BoolExpr``); non-``Claim`` inputs are
    lifted to helper Claims at the verb boundary per RFC #703.
    """
    a = _lift_to_claim(a, verb="exclusive", position="first argument")
    b = _lift_to_claim(b, verb="exclusive", position="second argument")
    helper = Claim(
        f"exactly one of {_claim_ref(a)} and {_claim_ref(b)} is true.",
        metadata={"generated": True, "helper_kind": "complement_result", "review": True},
    )
    action = Exclusive(
        label=label,
        rationale=rationale,
        background=list(background or []),
        a=a,
        b=b,
        helper=helper,
    )
    validate_no_self_warrant(action, helper)
    attach_reasoning(helper, action)
    return helper

exists

exists(variable: Variable, body: Any) -> Exists

Create an existential quantifier over a free variable.

Source code in gaia/engine/lang/dsl/formula.py
23
24
25
def exists(variable: Variable, body: Any) -> Exists:
    """Create an existential quantifier over a free variable."""
    return Exists(variable=variable, body=body)

export

export(*items: str | Knowledge) -> list[str]

Return root __all__ names for a package's public Knowledge surface.

The helper is intentionally small: it returns a plain list[str] and stores no hidden export state. Passing strings is equivalent to writing the names directly. Passing a Knowledge object resolves the object's public name from the caller's module or local scope, which keeps __all__ close to normal Python public-API conventions while avoiding string typos.

Source code in gaia/engine/lang/dsl/knowledge.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
def export(*items: str | Knowledge) -> list[str]:
    """Return root ``__all__`` names for a package's public Knowledge surface.

    The helper is intentionally small: it returns a plain ``list[str]`` and
    stores no hidden export state. Passing strings is equivalent to writing the
    names directly. Passing a ``Knowledge`` object resolves the object's public
    name from the caller's module or local scope, which keeps ``__all__`` close
    to normal Python public-API conventions while avoiding string typos.
    """
    namespace: dict[str, Any] = {}
    current = inspect.currentframe()
    frame = None
    try:
        frame = current.f_back if current is not None else None
        if frame is not None:
            namespace.update(frame.f_globals)
            namespace.update(frame.f_locals)
    finally:
        del frame
        del current

    names: list[str] = []
    for item in items:
        if isinstance(item, str):
            name = item
        elif isinstance(item, Knowledge):
            matches = [
                candidate
                for candidate, value in namespace.items()
                if value is item and not candidate.startswith("_")
            ]
            if not matches:
                raise ValueError(
                    "export() could not find a public caller-scope name for "
                    f"Knowledge object {item!r}; pass the name string explicitly"
                )
            if len(matches) > 1:
                joined = ", ".join(sorted(matches))
                raise ValueError(
                    "export() found multiple names for the same Knowledge object: "
                    f"{joined}; pass the intended name string explicitly"
                )
            name = matches[0]
        else:
            raise TypeError(
                "export() entries must be strings or Gaia Knowledge objects, "
                f"got {type(item).__name__}"
            )
        if name in names:
            raise ValueError(f"export() received duplicate export name {name!r}")
        names.append(name)
    return names

figure

figure(*, source: str | None = None, locator: str | None = None, path: str | None = None, caption: str | None = None, description: str | None = None, media_type: str | None = None, content: str | None = None, title: str | None = None) -> Note

Create a figure artifact note.

Source code in gaia/engine/lang/dsl/artifacts.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def figure(
    *,
    source: str | None = None,
    locator: str | None = None,
    path: str | None = None,
    caption: str | None = None,
    description: str | None = None,
    media_type: str | None = None,
    content: str | None = None,
    title: str | None = None,
) -> Note:
    """Create a figure artifact note."""
    return artifact(
        kind="figure",
        source=source,
        locator=locator,
        path=path,
        caption=caption,
        description=description,
        media_type=media_type,
        content=content,
        title=title,
    )

forall

forall(variable: Variable, body: Any) -> Forall

Create a universal quantifier over a free variable.

Source code in gaia/engine/lang/dsl/formula.py
18
19
20
def forall(variable: Variable, body: Any) -> Forall:
    """Create a universal quantifier over a free variable."""
    return Forall(variable=variable, body=body)

iff

iff(left: Any, right: Any) -> Iff

Create an equivalence formula.

Source code in gaia/engine/lang/dsl/formula.py
48
49
50
def iff(left: Any, right: Any) -> Iff:
    """Create an equivalence formula."""
    return Iff(left=left, right=right)

implies

implies(antecedent: Any, consequent: Any) -> Implies

Create an implication formula.

Source code in gaia/engine/lang/dsl/formula.py
43
44
45
def implies(antecedent: Any, consequent: Any) -> Implies:
    """Create an implication formula."""
    return Implies(antecedent=antecedent, consequent=consequent)

infer

infer(evidence: Claim | str | None = None, *args: Any, hypothesis: Claim | None = None, given: Claim | tuple[Claim, ...] | list[Claim] | None = (), background: list[Knowledge] | None = None, p_e_given_h: float | Claim | None = None, p_e_given_not_h: float | Claim | None = _DEFAULT_P_E_GIVEN_NOT_H_ARG, rationale: str = '', label: str | None = None, **legacy_kwargs: Any) -> Claim | Strategy

Bayesian inference. Returns the evidence Claim.

The canonical v6 shape is infer(evidence, hypothesis=..., ...). The old v5 infer([premises], conclusion, ...) form is preserved as a deprecated compatibility path.

Source code in gaia/engine/lang/dsl/infer_verb.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def infer(
    evidence: Claim | str | None = None,
    *args: Any,
    hypothesis: Claim | None = None,
    given: Claim | tuple[Claim, ...] | list[Claim] | None = (),
    background: list[Knowledge] | None = None,
    p_e_given_h: float | Claim | None = None,
    p_e_given_not_h: float | Claim | None = _DEFAULT_P_E_GIVEN_NOT_H_ARG,
    rationale: str = "",
    label: str | None = None,
    **legacy_kwargs: Any,
) -> Claim | Strategy:
    """Bayesian inference. Returns the evidence Claim.

    The canonical v6 shape is ``infer(evidence, hypothesis=..., ...)``. The old
    v5 ``infer([premises], conclusion, ...)`` form is preserved as a deprecated
    compatibility path.
    """
    legacy_evidence = cast(Any, evidence)
    if isinstance(legacy_evidence, (list, tuple)):
        return _legacy_infer(legacy_evidence, args, legacy_kwargs)

    if args:
        raise TypeError("v6 infer() accepts only one positional evidence argument")
    if legacy_kwargs:
        unexpected = next(iter(legacy_kwargs))
        raise TypeError(f"infer() got an unexpected keyword argument: '{unexpected}'")
    evidence = _resolve_evidence(evidence)
    evidence, hypothesis, given_tuple = _validate_infer_claims(
        hypothesis=hypothesis,
        evidence=evidence,
        p_e_given_h=p_e_given_h,
        given=given,
    )
    assert p_e_given_h is not None
    raw_p_e_given_not_h: Any = p_e_given_not_h
    p_e_given_not_h_defaulted = raw_p_e_given_not_h is _DEFAULT_P_E_GIVEN_NOT_H
    if p_e_given_not_h_defaulted:
        resolved_p_e_given_not_h: float | Claim | None = 0.5
    else:
        resolved_p_e_given_not_h = cast(float | Claim | None, raw_p_e_given_not_h)
    relation = _infer_relation(
        hypothesis=hypothesis,
        evidence=evidence,
        given_tuple=given_tuple,
        p_e_given_h=p_e_given_h,
        p_e_given_not_h=resolved_p_e_given_not_h,
        p_e_given_not_h_defaulted=p_e_given_not_h_defaulted,
    )
    helper = Claim(
        f"{_claim_ref(evidence)} statistically supports {_claim_ref(hypothesis)}.",
        metadata={
            "generated": True,
            "helper_kind": "likelihood",
            "review": True,
            "relation": relation,
        },
    )
    action = InferAction(
        label=label,
        rationale=rationale,
        background=list(background or []),
        hypothesis=hypothesis,
        evidence=evidence,
        given=given_tuple,
        p_e_given_h=p_e_given_h,
        p_e_given_not_h=resolved_p_e_given_not_h,
        p_e_given_not_h_defaulted=p_e_given_not_h_defaulted,
        helper=helper,
    )
    action.warrants.append(helper)
    validate_no_self_warrant(action, evidence)
    attach_reasoning(evidence, action)
    return evidence

land

land(*operands: Any) -> Land

Create a logical conjunction formula.

Source code in gaia/engine/lang/dsl/formula.py
28
29
30
def land(*operands: Any) -> Land:
    """Create a logical conjunction formula."""
    return Land(operands=tuple(operands))

lnot

lnot(operand: Any) -> Lnot

Create a logical negation formula.

Source code in gaia/engine/lang/dsl/formula.py
38
39
40
def lnot(operand: Any) -> Lnot:
    """Create a logical negation formula."""
    return Lnot(operand=operand)

lor

lor(*operands: Any) -> Lor

Create a logical disjunction formula.

Source code in gaia/engine/lang/dsl/formula.py
33
34
35
def lor(*operands: Any) -> Lor:
    """Create a logical disjunction formula."""
    return Lor(operands=tuple(operands))

materialize

materialize(scaffold: Scaffold, *, by: GaiaGraph | Claim | str | list[GaiaGraph | Claim | str] | tuple[GaiaGraph | Claim | str, ...], rationale: str = '', label: str | None = None, metadata: dict[str, Any] | None = None) -> MaterializationLink

Record a checked link from scaffold to formal graph records.

Source code in gaia/engine/lang/dsl/scaffold.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def materialize(
    scaffold: Scaffold,
    *,
    by: GaiaGraph
    | Claim
    | str
    | list[GaiaGraph | Claim | str]
    | tuple[GaiaGraph | Claim | str, ...],
    rationale: str = "",
    label: str | None = None,
    metadata: dict[str, Any] | None = None,
) -> MaterializationLink:
    """Record a checked link from scaffold to formal graph records."""
    if not isinstance(scaffold, Scaffold):
        raise TypeError("materialize scaffold must be a Scaffold")
    pkg = _materialization_package(scaffold)
    records = _resolve_materializers(scaffold, by)
    if not records:
        raise ValueError("materialize requires at least one by record")
    for record in records:
        if isinstance(record, Scaffold):
            raise TypeError("materialize by records must not be Scaffold records")
        if record._package is not pkg or record not in pkg.actions:
            raise ValueError("materialize by records must belong to the scaffold package")
    core_claims = _scaffold_core_claims(scaffold)
    core_ids = {id(claim) for claim in core_claims}
    if not any(_record_references_claims(record, core_ids) for record in records):
        raise ValueError("materialize by records must reference at least one scaffold core claims")
    _validate_pattern_consistency(scaffold, records)

    link = MaterializationLink(
        scaffold=scaffold,
        by=records,
        label=label,
        rationale=rationale,
        metadata=dict(metadata or {}),
    )
    pkg._register_materialization(link)
    return link

note

note(content: str, *, title: str | None = None, format: str = 'markdown', **metadata: Any) -> Note

Declare non-probabilistic contextual material.

Source code in gaia/engine/lang/dsl/knowledge.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def note(
    content: str,
    *,
    title: str | None = None,
    format: str = "markdown",
    **metadata: Any,
) -> Note:
    """Declare non-probabilistic contextual material."""
    provenance = metadata.pop("provenance", None)
    return Note(
        content=content.strip(),
        format=format,
        title=title,
        provenance=provenance or [],
        metadata=_flatten_metadata(metadata),
    )

observe

observe(conclusion: Any, *, value: Any = _OBSERVE_VALUE_SENTINEL, error: Any = None, given: Claim | tuple[Claim, ...] | list[Claim] | None = (), background: list[Knowledge] | None = None, source_refs: list[str] | None = None, rationale: str = '', label: str | None = None) -> Claim

Empirical observation.

Three authoring shapes:

  1. Discrete claim observationobserve(my_claim). A Boolean-valued expression such as a & b is lifted to an explicit helper Claim first. A no-premise observation pins the conclusion to 1 - CROMWELL_EPS. Use given= to record a conditional observation that does not pin the conclusion.
  2. Continuous quantity observationobserve(distribution, value=v, error=σ). Records a measurement event for a :class:Distribution-typed quantity. Returns a freshly minted :class:Claim representing the observation event (pinned to 1 - CROMWELL_EPS since the measurement was made), with metadata linking back to the underlying distribution. The compiler reads this linkage for audit and future posterior-CDF lowering. The current predicate-prior lowering still uses the Distribution's prior CDF and emits a warning when an observation targets the same Distribution.

value is the measured numeric value; error is either None for a noise-free observation, a scalar interpreted as the Gaussian additive standard deviation, or a :class:Distribution for a custom noise model.

  1. Variable observation (v0.6 unified-bayes path)observe(variable, value=v, error=σ). Records a measurement event for a primitive :class:Variable (the kind that appears as the observable of a Bayes predictive model). Writes the unified metadata["observation"] schema consumed by :func:gaia.engine.bayes.compare. Scalar error is sugared into an anonymous Normal(mu=0, sigma=error) so noise is always either None or a :class:Distribution Knowledge node.
Source code in gaia/engine/lang/dsl/support.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
def observe(
    conclusion: Any,
    *,
    value: Any = _OBSERVE_VALUE_SENTINEL,
    error: Any = None,
    given: Claim | tuple[Claim, ...] | list[Claim] | None = (),
    background: list[Knowledge] | None = None,
    source_refs: list[str] | None = None,
    rationale: str = "",
    label: str | None = None,
) -> Claim:
    """Empirical observation.

    Three authoring shapes:

    1. **Discrete claim observation** — ``observe(my_claim)``. A Boolean-valued
       expression such as ``a & b`` is lifted to an explicit helper Claim first.
       A no-premise observation pins the conclusion to ``1 - CROMWELL_EPS``.
       Use ``given=`` to record a conditional observation that does not pin the
       conclusion.
    2. **Continuous quantity observation** — ``observe(distribution,
       value=v, error=σ)``. Records a measurement event for a
       :class:`Distribution`-typed quantity. Returns a freshly minted
       :class:`Claim` representing the observation event (pinned to
       ``1 - CROMWELL_EPS`` since the measurement was made), with metadata
       linking back to the underlying distribution. The compiler reads this
       linkage for audit and future posterior-CDF lowering. The current
       predicate-prior lowering still uses the Distribution's prior CDF and
       emits a warning when an observation targets the same Distribution.

       ``value`` is the measured numeric value; ``error`` is either ``None``
       for a noise-free observation, a scalar interpreted as the Gaussian
       additive standard deviation, or a :class:`Distribution` for a
       custom noise model.

    3. **Variable observation (v0.6 unified-bayes path)** —
       ``observe(variable, value=v, error=σ)``. Records a measurement event
       for a primitive :class:`Variable` (the kind that appears as the
       observable of a Bayes predictive model). Writes the unified
       ``metadata["observation"]`` schema consumed by
       :func:`gaia.engine.bayes.compare`. Scalar ``error`` is sugared into
       an anonymous ``Normal(mu=0, sigma=error)`` so noise is always either
       ``None`` or a :class:`Distribution` Knowledge node.
    """
    _warn_source_refs_deprecated(source_refs)

    if isinstance(conclusion, Distribution):
        if value is _OBSERVE_VALUE_SENTINEL:
            raise TypeError(
                "observe(distribution, ...) requires `value=` (the measured "
                "numeric value). For a discrete claim observation use "
                "observe(claim) without value/error."
            )
        if given:
            raise TypeError(
                "observe(distribution, value=..., given=...) is not supported "
                "— continuous observations are unconditional measurement "
                "events. To express a conditional measurement, observe a "
                "Claim wrapping the conditioning premise."
            )
        return _observe_continuous(
            conclusion,
            value=value,
            error=error,
            background=background,
            source_refs=source_refs,
            rationale=rationale,
            label=label,
        )

    if isinstance(conclusion, Variable):
        if value is _OBSERVE_VALUE_SENTINEL:
            raise TypeError(
                "observe(variable, ...) requires `value=` (the measured numeric value)."
            )
        if given:
            raise TypeError(
                "observe(variable, value=..., given=...) is not supported "
                "— variable observations are unconditional measurement "
                "events. To express a conditional measurement, observe a "
                "Claim wrapping the conditioning premise."
            )
        return _observe_variable(
            conclusion,
            value=value,
            error=error,
            background=background,
            source_refs=source_refs,
            rationale=rationale,
            label=label,
        )

    if value is not _OBSERVE_VALUE_SENTINEL or error is not None:
        raise TypeError(
            "observe(..., value=..., error=...) only applies to Distribution "
            "or Variable targets. For discrete claim observations omit value/error."
        )

    if isinstance(conclusion, str):
        conclusion = Claim(conclusion)
    else:
        conclusion = _lift_to_claim(conclusion, verb="observe", position="conclusion")
    assert isinstance(conclusion, Claim)  # narrow Any back to Claim for mypy
    given_tuple = tuple(
        _lift_to_claim(g, verb="observe", position=f"given[{i}]")
        for i, g in enumerate(_as_given_tuple(given))
    )
    warrant = _implication_warrant(
        "observe",
        given=given_tuple,
        conclusion=conclusion,
        rationale=rationale,
    )
    action = Observe(
        label=label,
        rationale=rationale,
        background=list(background or []),
        warrants=[warrant],
        metadata={"source_refs": list(source_refs)} if source_refs else {},
        conclusion=conclusion,
        given=given_tuple,
    )
    if not given_tuple:
        _pin_observed_claim(conclusion)
    validate_no_self_warrant(action, conclusion)
    attach_reasoning(conclusion, action)
    return conclusion

parameter

parameter(variable: Variable, value: Any, *, content: str | None = None, describe: str | None = None, title: str | None = None, format: str = 'markdown', background: list[Knowledge] | None = None, provenance: list[dict[str, str]] | None = None, prior: float | None = None, label: str | None = None, metadata: dict[str, Any] | None = None) -> Claim

Declare that a primitive Variable takes a concrete value.

Source code in gaia/engine/lang/dsl/sugar.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def parameter(
    variable: Variable,
    value: Any,
    *,
    content: str | None = None,
    describe: str | None = None,
    title: str | None = None,
    format: str = "markdown",
    background: list[Knowledge] | None = None,
    provenance: list[dict[str, str]] | None = None,
    prior: float | None = None,
    label: str | None = None,
    metadata: dict[str, Any] | None = None,
) -> Claim:
    """Declare that a primitive Variable takes a concrete value."""
    formula = equals(variable, _constant_for(variable, value))
    result = claim(
        _content_text(content, describe, _parameter_content(variable, value)),
        title=title,
        format=format,
        background=background,
        provenance=provenance,
        prior=prior,
        formula=formula,
        kind=ClaimKind.PARAMETER,
        metadata=metadata or {},
    )
    result.label = label
    return result

question

question(content: str, *, title: str | None = None, format: str = 'markdown', **metadata: Any) -> Question

Declare a research question. No probability, no BP participation.

Source code in gaia/engine/lang/dsl/knowledge.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def question(
    content: str,
    *,
    title: str | None = None,
    format: str = "markdown",
    **metadata: Any,
) -> Question:
    """Declare a research question. No probability, no BP participation."""
    provenance = metadata.pop("provenance", None)
    targets = metadata.pop("targets", [])
    return Question(
        content=content.strip(),
        format=format,
        title=title,
        targets=targets,
        provenance=provenance or [],
        metadata=_flatten_metadata(metadata),
    )

is_formula

is_formula(obj: object) -> bool

Return whether an object is explicitly tagged as a Formula node.

Source code in gaia/engine/lang/formula/predicate.py
25
26
27
def is_formula(obj: object) -> bool:
    """Return whether an object is explicitly tagged as a Formula node."""
    return getattr(obj, "__gaia_formula__", False) is True

is_term

is_term(obj: object) -> bool

Strict check — only objects explicitly tagged as terms qualify.

Source code in gaia/engine/lang/formula/term.py
28
29
30
def is_term(obj: object) -> bool:
    """Strict check — only objects explicitly tagged as terms qualify."""
    return getattr(obj, "__gaia_term__", False) is True

roles_for_claim

roles_for_claim(claim: Claim, graph: ActionGraph, *, include_background: bool = True, include_warrants: bool = True) -> tuple[RoleOccurrence, ...]

Return all authored action roles for claim.

Source code in gaia/engine/lang/runtime/roles.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def roles_for_claim(
    claim: Claim,
    graph: ActionGraph,
    *,
    include_background: bool = True,
    include_warrants: bool = True,
) -> tuple[RoleOccurrence, ...]:
    """Return all authored action roles for ``claim``."""
    return tuple(
        occurrence
        for occurrence in _iter_role_occurrences(
            graph,
            include_background=include_background,
            include_warrants=include_warrants,
        )
        if occurrence.claim is claim
    )

roles_for_package

roles_for_package(graph: ActionGraph, *, include_background: bool = True, include_warrants: bool = True) -> dict[Claim, tuple[RoleOccurrence, ...]]

Index authored action roles by claim identity.

Source code in gaia/engine/lang/runtime/roles.py
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
def roles_for_package(
    graph: ActionGraph,
    *,
    include_background: bool = True,
    include_warrants: bool = True,
) -> dict[Claim, tuple[RoleOccurrence, ...]]:
    """Index authored action roles by claim identity."""
    roles: dict[Claim, list[RoleOccurrence]] = defaultdict(list)
    for occurrence in _iter_role_occurrences(
        graph,
        include_background=include_background,
        include_warrants=include_warrants,
    ):
        roles[occurrence.claim].append(occurrence)
    return {claim: tuple(occurrences) for claim, occurrences in roles.items()}

Beta

Beta(content: str, *, alpha: Any, beta: Any, **kwargs: Any) -> Distribution

Create a Beta-distributed continuous quantity with a name.

Beta shape parameters alpha and beta are dimensionless.

Source code in gaia/engine/lang/runtime/distribution.py
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
def Beta(
    content: str,
    *,
    alpha: Any,
    beta: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Beta-distributed continuous quantity with a name.

    Beta shape parameters ``alpha`` and ``beta`` are dimensionless.
    """
    from gaia.engine.bayes.distributions.continuous import Beta as _BaseBeta

    return _build_distribution(
        content,
        impl_cls=_BaseBeta,
        raw_params={"alpha": alpha, "beta": beta},
        dimensionless_params=("alpha", "beta"),
        distribution_name="Beta",
        kwargs=kwargs,
    )

BetaBinomial

BetaBinomial(content: str, *, n: Any, alpha: Any, beta: Any, **kwargs: Any) -> Distribution

Create a Beta-Binomial-distributed discrete quantity with a name.

Predictive distribution of Binomial(n, p) integrated over p ~ Beta(alpha, beta). All three parameters are dimensionless. The closed-form uniform marginal BetaBinomial(n, 1, 1) is the canonical diffuse reference: P(k) = 1 / (n + 1) for k ∈ [0, n].

Source code in gaia/engine/lang/runtime/distribution.py
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
def BetaBinomial(
    content: str,
    *,
    n: Any,
    alpha: Any,
    beta: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Beta-Binomial-distributed discrete quantity with a name.

    Predictive distribution of ``Binomial(n, p)`` integrated over
    ``p ~ Beta(alpha, beta)``. All three parameters are dimensionless.
    The closed-form uniform marginal ``BetaBinomial(n, 1, 1)`` is the
    canonical diffuse reference: ``P(k) = 1 / (n + 1)`` for ``k ∈ [0, n]``.
    """
    from gaia.engine.bayes.distributions.discrete import BetaBinomial as _BaseBetaBinomial

    return _build_distribution(
        content,
        impl_cls=_BaseBetaBinomial,
        raw_params={"n": n, "alpha": alpha, "beta": beta},
        dimensionless_params=("n", "alpha", "beta"),
        distribution_name="BetaBinomial",
        kwargs=kwargs,
    )

Binomial

Binomial(content: str, *, n: Any, p: Any, **kwargs: Any) -> Distribution

Create a Binomial-distributed discrete quantity with a name.

n and p are dimensionless.

Source code in gaia/engine/lang/runtime/distribution.py
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
def Binomial(
    content: str,
    *,
    n: Any,
    p: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Binomial-distributed discrete quantity with a name.

    ``n`` and ``p`` are dimensionless.
    """
    from gaia.engine.bayes.distributions.discrete import Binomial as _BaseBinomial

    return _build_distribution(
        content,
        impl_cls=_BaseBinomial,
        raw_params={"n": n, "p": p},
        dimensionless_params=("n", "p"),
        distribution_name="Binomial",
        kwargs=kwargs,
    )

Cauchy

Cauchy(content: str, *, mu: Any, gamma: Any, **kwargs: Any) -> Distribution

Create a Cauchy-distributed continuous quantity with a name.

mu and gamma share the location/scale unit of the underlying random variable.

Source code in gaia/engine/lang/runtime/distribution.py
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
def Cauchy(
    content: str,
    *,
    mu: Any,
    gamma: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Cauchy-distributed continuous quantity with a name.

    ``mu`` and ``gamma`` share the location/scale unit of the underlying
    random variable.
    """
    from gaia.engine.bayes.distributions.continuous import Cauchy as _BaseCauchy

    return _build_distribution(
        content,
        impl_cls=_BaseCauchy,
        raw_params={"mu": mu, "gamma": gamma},
        location_scale_group=("mu", "gamma"),
        distribution_name="Cauchy",
        kwargs=kwargs,
    )

ChiSquared

ChiSquared(content: str, *, df: Any, **kwargs: Any) -> Distribution

Create a Chi-squared distributed continuous quantity with a name.

df is dimensionless.

Source code in gaia/engine/lang/runtime/distribution.py
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
def ChiSquared(
    content: str,
    *,
    df: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Chi-squared distributed continuous quantity with a name.

    ``df`` is dimensionless.
    """
    from gaia.engine.bayes.distributions.continuous import ChiSquared as _BaseChiSquared

    return _build_distribution(
        content,
        impl_cls=_BaseChiSquared,
        raw_params={"df": df},
        dimensionless_params=("df",),
        distribution_name="ChiSquared",
        kwargs=kwargs,
    )

Exponential

Exponential(content: str, *, rate: Any, **kwargs: Any) -> Distribution

Create an Exponential-distributed continuous quantity with a name.

rate may be a bare scalar or a :class:gaia.unit.Quantity (typically 1 / time). The corresponding random variable's unit is the inverse of rate's unit; for predicate / observe consistency we record that inverse unit as the distribution's canonical metadata["unit"].

Source code in gaia/engine/lang/runtime/distribution.py
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
def Exponential(
    content: str,
    *,
    rate: Any,
    **kwargs: Any,
) -> Distribution:
    """Create an Exponential-distributed continuous quantity with a name.

    ``rate`` may be a bare scalar or a :class:`gaia.unit.Quantity` (typically
    ``1 / time``). The corresponding random variable's unit is the inverse of
    ``rate``'s unit; for predicate / observe consistency we record that
    inverse unit as the distribution's canonical ``metadata["unit"]``.
    """
    from gaia.engine.bayes.distributions.continuous import Exponential as _BaseExponential

    return _build_distribution(
        content,
        impl_cls=_BaseExponential,
        raw_params={"rate": rate},
        inverse_unit_carriers=("rate",),
        distribution_name="Exponential",
        kwargs=kwargs,
    )

Gamma

Gamma(content: str, *, alpha: Any, rate: Any, **kwargs: Any) -> Distribution

Create a Gamma-distributed continuous quantity with a name.

alpha is dimensionless; rate may carry the inverse unit of the underlying random variable (typically 1 / x).

Source code in gaia/engine/lang/runtime/distribution.py
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
def Gamma(
    content: str,
    *,
    alpha: Any,
    rate: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Gamma-distributed continuous quantity with a name.

    ``alpha`` is dimensionless; ``rate`` may carry the inverse unit of the
    underlying random variable (typically ``1 / x``).
    """
    from gaia.engine.bayes.distributions.continuous import Gamma as _BaseGamma

    return _build_distribution(
        content,
        impl_cls=_BaseGamma,
        raw_params={"alpha": alpha, "rate": rate},
        dimensionless_params=("alpha",),
        inverse_unit_carriers=("rate",),
        distribution_name="Gamma",
        kwargs=kwargs,
    )

LogNormal

LogNormal(content: str, *, mu: Any, sigma: Any, **kwargs: Any) -> Distribution

Create a LogNormal-distributed continuous quantity with a name.

The LogNormal parameters live in log-space; mu and sigma must be dimensionless scalars. Encode the unit of the underlying random variable in the content string (e.g. LogNormal("k / s^-1", mu=log(1e-3), sigma=2)).

Source code in gaia/engine/lang/runtime/distribution.py
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
def LogNormal(
    content: str,
    *,
    mu: Any,
    sigma: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a LogNormal-distributed continuous quantity with a name.

    The LogNormal parameters live in log-space; ``mu`` and ``sigma`` must be
    dimensionless scalars. Encode the unit of the underlying random variable
    in the content string (e.g. ``LogNormal("k / s^-1", mu=log(1e-3), sigma=2)``).
    """
    from gaia.engine.bayes.distributions.continuous import LogNormal as _BaseLogNormal

    return _build_distribution(
        content,
        impl_cls=_BaseLogNormal,
        raw_params={"mu": mu, "sigma": sigma},
        dimensionless_params=("mu", "sigma"),
        distribution_name="LogNormal",
        kwargs=kwargs,
    )

Normal

Normal(content: str, *, mu: Any, sigma: Any, **kwargs: Any) -> Distribution

Create a Normal-distributed continuous quantity with a name.

mu and sigma may both be bare scalars or both be :class:gaia.unit.Quantity values sharing a unit; mixing them raises.

Source code in gaia/engine/lang/runtime/distribution.py
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
def Normal(
    content: str,
    *,
    mu: Any,
    sigma: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Normal-distributed continuous quantity with a name.

    ``mu`` and ``sigma`` may both be bare scalars or both be
    :class:`gaia.unit.Quantity` values sharing a unit; mixing them raises.
    """
    from gaia.engine.bayes.distributions.continuous import Normal as _BaseNormal

    return _build_distribution(
        content,
        impl_cls=_BaseNormal,
        raw_params={"mu": mu, "sigma": sigma},
        location_scale_group=("mu", "sigma"),
        distribution_name="Normal",
        kwargs=kwargs,
    )

Poisson

Poisson(content: str, *, rate: Any, **kwargs: Any) -> Distribution

Create a Poisson-distributed discrete quantity with a name.

rate is the dimensionless expected count for the interval encoded by the quantity name. Pass a bare scalar; unit-typed rates are rejected.

Source code in gaia/engine/lang/runtime/distribution.py
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
def Poisson(
    content: str,
    *,
    rate: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Poisson-distributed discrete quantity with a name.

    ``rate`` is the dimensionless expected count for the interval encoded by
    the quantity name. Pass a bare scalar; unit-typed rates are rejected.
    """
    from gaia.engine.bayes.distributions.discrete import Poisson as _BasePoisson

    return _build_distribution(
        content,
        impl_cls=_BasePoisson,
        raw_params={"rate": rate},
        dimensionless_params=("rate",),
        distribution_name="Poisson",
        kwargs=kwargs,
    )

StudentT

StudentT(content: str, *, df: Any, mu: Any, sigma: Any, **kwargs: Any) -> Distribution

Create a Student-t distributed continuous quantity with a name.

df is dimensionless; mu and sigma share the location/scale unit of the underlying random variable.

Source code in gaia/engine/lang/runtime/distribution.py
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
def StudentT(
    content: str,
    *,
    df: Any,
    mu: Any,
    sigma: Any,
    **kwargs: Any,
) -> Distribution:
    """Create a Student-t distributed continuous quantity with a name.

    ``df`` is dimensionless; ``mu`` and ``sigma`` share the location/scale
    unit of the underlying random variable.
    """
    from gaia.engine.bayes.distributions.continuous import StudentT as _BaseStudentT

    return _build_distribution(
        content,
        impl_cls=_BaseStudentT,
        raw_params={"df": df, "mu": mu, "sigma": sigma},
        location_scale_group=("mu", "sigma"),
        dimensionless_params=("df",),
        distribution_name="StudentT",
        kwargs=kwargs,
    )