Skip to content

Authoring DSL API

Status: Generated from current Python docstrings and type hints.

Public authoring helpers for knowledge packages. Start here when checking the Python surface that package authors import.

gaia.engine.lang.dsl

Public Gaia Lang DSL helper functions.

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}})

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,
    )

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

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)

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)

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)

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))

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

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

context

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

Deprecated compatibility wrapper for note().

Source code in gaia/engine/lang/dsl/knowledge.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def context(
    content: str,
    *,
    title: str | None = None,
    format: str = "markdown",
    **metadata: Any,
) -> Note:
    """Deprecated compatibility wrapper for note()."""
    _warn_deprecated_note_alias("context")
    provenance = metadata.pop("provenance", None)
    return Note(
        content=content.strip(),
        format=format,
        title=title,
        provenance=provenance or [],
        metadata=_metadata_with_legacy_kind(metadata, "context"),
    )

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

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),
    )

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),
    )

setting

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

Deprecated compatibility wrapper for note().

Source code in gaia/engine/lang/dsl/knowledge.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def setting(
    content: str,
    *,
    title: str | None = None,
    format: str = "markdown",
    **metadata: Any,
) -> Note:
    """Deprecated compatibility wrapper for note()."""
    _warn_deprecated_note_alias("setting")
    provenance = metadata.pop("provenance", None)
    return Note(
        content=content.strip(),
        format=format,
        title=title,
        provenance=provenance or [],
        metadata=_metadata_with_legacy_kind(metadata, "setting"),
    )

complement

complement(a: Knowledge, b: Knowledge, *, reason: str = '', prior: float | None = None) -> Knowledge

A != B (XOR). Creates Operator, returns helper claim.

Source code in gaia/engine/lang/dsl/operators.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def complement(
    a: Knowledge, b: Knowledge, *, reason: str = "", prior: float | None = None
) -> Knowledge:
    """A != B (XOR). Creates Operator, returns helper claim."""
    _warn_deprecated_operator(
        "complement",
        "exclusive(a, b, rationale=...) for reviewable relations or "
        "claim(formula=lnot(iff(ClaimAtom(...), ClaimAtom(...)))) for structural formulas",
    )
    _validate_reason_prior(reason, prior)
    helper = Knowledge(
        content=f"opposite_truth({a.label or 'A'}, {b.label or 'B'})",
        type="claim",
        metadata=_helper_metadata("complement_result", prior),
    )
    Operator(operator="complement", variables=[a, b], conclusion=helper, reason=reason)
    return helper

contradiction

contradiction(a: Knowledge, b: Knowledge, *, reason: str = '', prior: float | None = None) -> Knowledge

not(A and B). Creates Operator, returns helper claim.

Source code in gaia/engine/lang/dsl/operators.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def contradiction(
    a: Knowledge, b: Knowledge, *, reason: str = "", prior: float | None = None
) -> Knowledge:
    """not(A and B). Creates Operator, returns helper claim."""
    _warn_deprecated_operator(
        "contradiction",
        "contradict(a, b, rationale=...) for reviewable relations or "
        "claim(formula=lnot(land(ClaimAtom(...), ...))) for structural formulas",
    )
    _validate_reason_prior(reason, prior)
    helper = Knowledge(
        content=f"not_both_true({a.label or 'A'}, {b.label or 'B'})",
        type="claim",
        metadata=_helper_metadata("contradiction_result", prior),
    )
    Operator(operator="contradiction", variables=[a, b], conclusion=helper, reason=reason)
    return helper

disjunction

disjunction(*claims: Knowledge, reason: str = '', prior: float | None = None) -> Knowledge

At least one true. Creates Operator, returns helper claim.

Source code in gaia/engine/lang/dsl/operators.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def disjunction(*claims: Knowledge, reason: str = "", prior: float | None = None) -> Knowledge:
    """At least one true. Creates Operator, returns helper claim."""
    _warn_deprecated_operator(
        "disjunction",
        "claim(formula=lor(ClaimAtom(...), ...)) for structural formulas",
    )
    _validate_reason_prior(reason, prior)
    labels = ", ".join(c.label or f"C{i}" for i, c in enumerate(claims))
    helper = Knowledge(
        content=f"any_true({labels})",
        type="claim",
        metadata=_helper_metadata("disjunction_result", prior),
    )
    Operator(operator="disjunction", variables=list(claims), conclusion=helper, reason=reason)
    return helper

equivalence

equivalence(a: Knowledge, b: Knowledge, *, reason: str = '', prior: float | None = None) -> Knowledge

A = B. Creates Operator, returns helper claim.

Source code in gaia/engine/lang/dsl/operators.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def equivalence(
    a: Knowledge, b: Knowledge, *, reason: str = "", prior: float | None = None
) -> Knowledge:
    """A = B. Creates Operator, returns helper claim."""
    _warn_deprecated_operator(
        "equivalence",
        "equal(a, b, rationale=...) for reviewable relations or "
        "claim(formula=iff(ClaimAtom(...), ClaimAtom(...))) for structural formulas",
    )
    _validate_reason_prior(reason, prior)
    helper = Knowledge(
        content=f"same_truth({a.label or 'A'}, {b.label or 'B'})",
        type="claim",
        metadata=_helper_metadata("equivalence_result", prior),
    )
    Operator(operator="equivalence", variables=[a, b], conclusion=helper, reason=reason)
    return helper

and_

and_(*claims: Claim) -> Claim

Construct a Boolean conjunction expression over two or more Claims.

Source code in gaia/engine/lang/dsl/propositional.py
47
48
49
50
51
52
53
54
55
56
def and_(*claims: Claim) -> Claim:
    """Construct a Boolean conjunction expression over two or more Claims."""
    _warn_deprecated_helper("and_", "claim(formula=land(ClaimAtom(...), ...))")
    if len(claims) < 2:
        raise ValueError("and_() requires at least two claims")
    _validate_claims(claims, "and_")
    labels = ", ".join(_claim_ref(claim) for claim in claims)
    helper = _expression_helper(f"all_true({labels})", "conjunction_result")
    Operator(operator="conjunction", variables=list(claims), conclusion=helper)
    return helper

not_

not_(claim: Claim) -> Claim

Construct the Boolean negation expression not claim.

Source code in gaia/engine/lang/dsl/propositional.py
38
39
40
41
42
43
44
def not_(claim: Claim) -> Claim:
    """Construct the Boolean negation expression ``not claim``."""
    _warn_deprecated_helper("not_", "claim(formula=lnot(ClaimAtom(...)))")
    _validate_claims((claim,), "not_")
    helper = _expression_helper(f"not({_claim_ref(claim)})", "negation_result")
    Operator(operator="negation", variables=[claim], conclusion=helper)
    return helper

or_

or_(*claims: Claim) -> Claim

Construct a Boolean disjunction expression over two or more Claims.

Source code in gaia/engine/lang/dsl/propositional.py
59
60
61
62
63
64
65
66
67
68
def or_(*claims: Claim) -> Claim:
    """Construct a Boolean disjunction expression over two or more Claims."""
    _warn_deprecated_helper("or_", "claim(formula=lor(ClaimAtom(...), ...))")
    if len(claims) < 2:
        raise ValueError("or_() requires at least two claims")
    _validate_claims(claims, "or_")
    labels = ", ".join(_claim_ref(claim) for claim in claims)
    helper = _expression_helper(f"any_true({labels})", "disjunction_result")
    Operator(operator="disjunction", variables=list(claims), conclusion=helper)
    return helper

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

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

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

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,
    )

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,
    )

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

abduction

abduction(support_h: Strategy, support_alt: Strategy, comparison: Strategy, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Ternary hypothesis comparison (IBE).

Takes two support strategies and a compare strategy. The compare strategy provides the conclusion (comparison_claim).

Parameters:

Name Type Description Default
support_h Strategy

Support for the primary theory.

required
support_alt Strategy

Support for the alternative theory.

required
comparison Strategy

compare(pred_h, pred_alt, obs) strategy.

required
background list[Knowledge] | None

Optional background knowledge.

None
reason ReasonInput

Warrant text for the composition validity.

''

Returns:

Type Description
Strategy

CompositeStrategy whose conclusion is comparison.conclusion.

Source code in gaia/engine/lang/dsl/strategies.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
def abduction(
    support_h: Strategy,
    support_alt: Strategy,
    comparison: Strategy,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Ternary hypothesis comparison (IBE).

    Takes two support strategies and a compare strategy.
    The compare strategy provides the conclusion (comparison_claim).

    Args:
        support_h: Support for the primary theory.
        support_alt: Support for the alternative theory.
        comparison: compare(pred_h, pred_alt, obs) strategy.
        background: Optional background knowledge.
        reason: Warrant text for the composition validity.

    Returns:
        CompositeStrategy whose conclusion is ``comparison.conclusion``.
    """
    conclusion = _validate_abduction_inputs(support_h, support_alt, comparison)
    comp_warrant = _composition_warrant(
        f"abduction_validity({support_h.type}, {support_alt.type}, {comparison.type})",
        reason,
    )
    all_premises = _unique_premises([support_h, support_alt, comparison])

    strategy = Strategy(
        type="abduction",
        premises=all_premises,
        conclusion=conclusion,
        background=background or [],
        reason=reason,
        sub_strategies=[support_h, support_alt, comparison],
        composition_warrant=comp_warrant,
        metadata={},
    )
    if conclusion is not None:
        _attach_strategy(conclusion, strategy)
    return strategy

analogy

analogy(source: Knowledge, target: Knowledge, bridge: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Analogy lowered via the canonical IR formalizer at compile time.

Source code in gaia/engine/lang/dsl/strategies.py
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
def analogy(
    source: Knowledge,
    target: Knowledge,
    bridge: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Analogy lowered via the canonical IR formalizer at compile time."""
    return _named_strategy(
        "analogy",
        premises=[source, bridge],
        conclusion=target,
        background=background,
        reason=reason,
    )

case_analysis

case_analysis(exhaustiveness: Knowledge, cases: list[tuple[Knowledge, Knowledge]], conclusion: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Case analysis lowered via the canonical IR formalizer at compile time.

Source code in gaia/engine/lang/dsl/strategies.py
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
def case_analysis(
    exhaustiveness: Knowledge,
    cases: list[tuple[Knowledge, Knowledge]],
    conclusion: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Case analysis lowered via the canonical IR formalizer at compile time."""
    return _named_strategy(
        "case_analysis",
        premises=[exhaustiveness, *_flatten_pairs(cases, name="case_analysis")],
        conclusion=conclusion,
        background=background,
        reason=reason,
    )

compare

compare(pred_h: Knowledge, pred_alt: Knowledge, observation: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '', prior: float | None = None) -> Strategy

Compare two predictions against observation via matching + inferential ordering.

Compiles to

equivalence(pred_h, obs) -> H_match1 (does pred_h match obs?) equivalence(pred_alt, obs) -> H_match2 (does pred_alt match obs?) implication(H_match2, H_match1) -> comparison_claim (if alt matches, does h also match?)

3 warrants. First arg is claimed-better. Also usable as standalone A/B test. The auto-generated comparison_claim becomes the strategy's conclusion. prior -> confidence for the comparison implication warrant.

Source code in gaia/engine/lang/dsl/strategies.py
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
def compare(
    pred_h: Knowledge,
    pred_alt: Knowledge,
    observation: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
    prior: float | None = None,
) -> Strategy:
    """Compare two predictions against observation via matching + inferential ordering.

    Compiles to:
      equivalence(pred_h, obs) -> H_match1 (does pred_h match obs?)
      equivalence(pred_alt, obs) -> H_match2 (does pred_alt match obs?)
      implication(H_match2, H_match1) -> comparison_claim (if alt matches, does h also match?)

    3 warrants. First arg is claimed-better. Also usable as standalone A/B test.
    The auto-generated comparison_claim becomes the strategy's conclusion.
    prior -> confidence for the comparison implication warrant.
    """
    _validate_reason_prior(reason, prior)
    metadata: dict[str, Any] = {}
    if prior is not None:
        metadata["prior"] = prior
    comparison_claim = Knowledge(
        content=f"compare({pred_h.content}, {pred_alt.content}, {observation.content})",
        type="claim",
        metadata={"helper_kind": "comparison_claim", "generated": True},
    )
    return _named_strategy(
        "compare",
        premises=[pred_h, pred_alt, observation],
        conclusion=comparison_claim,
        background=background,
        reason=reason,
        metadata=metadata,
    )

composite

composite(premises: list[Knowledge], conclusion: Knowledge, *, sub_strategies: list[Strategy], background: list[Knowledge] | None = None, reason: ReasonInput = '', type: str = 'infer') -> Strategy

Hierarchical composition lowered to IR CompositeStrategy.

Source code in gaia/engine/lang/dsl/strategies.py
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
def composite(
    premises: list[Knowledge],
    conclusion: Knowledge,
    *,
    sub_strategies: list[Strategy],
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
    type: str = "infer",
) -> Strategy:
    """Hierarchical composition lowered to IR CompositeStrategy."""
    return _composite_strategy(
        type_=type,
        premises=premises,
        conclusion=conclusion,
        sub_strategies=sub_strategies,
        background=background,
        reason=reason,
    )

deduction

deduction(premises: list[Knowledge], conclusion: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '', prior: float | None = None) -> Strategy

Deduction lowered via the canonical IR formalizer at compile time.

prior is accepted for legacy source compatibility. Current BP lowering treats deduction as hard Jaynes conditional implication; review gates publication quality, not the local inference preview or proof probability.

Source code in gaia/engine/lang/dsl/strategies.py
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
def deduction(
    premises: list[Knowledge],
    conclusion: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
    prior: float | None = None,
) -> Strategy:
    """Deduction lowered via the canonical IR formalizer at compile time.

    ``prior`` is accepted for legacy source compatibility. Current BP lowering
    treats deduction as hard Jaynes conditional implication; review gates
    publication quality, not the local inference preview or proof probability.
    """
    if len(premises) < 1:
        raise ValueError("deduction() requires at least 1 premise")
    _validate_reason_prior(reason, prior)
    metadata: dict[str, Any] | None = None
    if prior is not None:
        metadata = {"prior": prior}
    return _named_strategy(
        "deduction",
        premises=premises,
        conclusion=conclusion,
        background=background,
        reason=reason,
        metadata=metadata,
    )

elimination

elimination(exhaustiveness: Knowledge, excluded: list[tuple[Knowledge, Knowledge]], survivor: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Elimination lowered via the canonical IR formalizer at compile time.

Source code in gaia/engine/lang/dsl/strategies.py
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
def elimination(
    exhaustiveness: Knowledge,
    excluded: list[tuple[Knowledge, Knowledge]],
    survivor: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Elimination lowered via the canonical IR formalizer at compile time."""
    return _named_strategy(
        "elimination",
        premises=[exhaustiveness, *_flatten_pairs(excluded, name="elimination")],
        conclusion=survivor,
        background=background,
        reason=reason,
    )

extrapolation

extrapolation(source: Knowledge, target: Knowledge, continuity: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Extrapolation lowered via the canonical IR formalizer at compile time.

Source code in gaia/engine/lang/dsl/strategies.py
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
def extrapolation(
    source: Knowledge,
    target: Knowledge,
    continuity: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Extrapolation lowered via the canonical IR formalizer at compile time."""
    return _named_strategy(
        "extrapolation",
        premises=[source, continuity],
        conclusion=target,
        background=background,
        reason=reason,
    )

fills

fills(source: Knowledge, target: Knowledge, *, mode: Literal['deduction', 'infer'] | None = None, strength: Literal['exact', 'partial', 'conditional'] = 'exact', background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Declare that a source claim fills a target premise interface.

Source code in gaia/engine/lang/dsl/strategies.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
def fills(
    source: Knowledge,
    target: Knowledge,
    *,
    mode: Literal["deduction", "infer"] | None = None,
    strength: Literal["exact", "partial", "conditional"] = "exact",
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Declare that a source claim fills a target premise interface."""
    if strength not in {"exact", "partial", "conditional"}:
        raise ValueError("fills() strength must be one of: exact, partial, conditional")
    if mode is not None and mode not in {"deduction", "infer"}:
        raise ValueError("fills() mode must be one of: deduction, infer")
    if source.type != "claim":
        raise ValueError("fills() requires source.type == 'claim'")
    if target.type != "claim":
        raise ValueError("fills() requires target.type == 'claim'")

    resolved_mode = mode
    if resolved_mode is None:
        resolved_mode = "deduction" if strength == "exact" else "infer"

    metadata = {
        "gaia": {
            "relation": {
                "type": "fills",
                "strength": strength,
                "mode": resolved_mode,
            }
        }
    }

    if resolved_mode == "deduction":
        return _named_strategy(
            "deduction",
            premises=[source],
            conclusion=target,
            background=background,
            reason=reason,
            metadata=metadata,
        )
    return _leaf_strategy(
        "infer",
        premises=[source],
        conclusion=target,
        background=background,
        reason=reason,
        metadata=metadata,
    )

induction

induction(support_1: Strategy, support_2: Strategy, law: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Binary CompositeStrategy: two supports jointly confirm a law.

Chains via induction(prev_induction, new_support, law).

Parameters:

Name Type Description Default
support_1 Strategy

First support (FormalStrategy or previous induction).

required
support_2 Strategy

Second support (FormalStrategy).

required
law Knowledge

The Knowledge being supported.

required
background list[Knowledge] | None

Optional background knowledge.

None
reason ReasonInput

Warrant text for the composition validity.

''

Returns:

Type Description
Strategy

CompositeStrategy whose conclusion is law.

Source code in gaia/engine/lang/dsl/strategies.py
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
def induction(
    support_1: Strategy,
    support_2: Strategy,
    law: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Binary CompositeStrategy: two supports jointly confirm a law.

    Chains via ``induction(prev_induction, new_support, law)``.

    Args:
        support_1: First support (FormalStrategy or previous induction).
        support_2: Second support (FormalStrategy).
        law: The Knowledge being supported.
        background: Optional background knowledge.
        reason: Warrant text for the composition validity.

    Returns:
        CompositeStrategy whose conclusion is *law*.
    """
    _validate_induction_inputs(support_1, support_2, law)
    composition_warrant = _composition_warrant(
        "Are observations independent? Do they support the same law?",
        reason,
    )
    all_premises = _induction_premises(support_1, support_2, law)

    strategy = Strategy(
        type="induction",
        premises=all_premises,
        conclusion=law,
        background=background or [],
        reason=reason,
        sub_strategies=[support_1, support_2],
        composition_warrant=composition_warrant,
    )
    _attach_strategy(law, strategy)
    return strategy

mathematical_induction

mathematical_induction(base: Knowledge, step: Knowledge, conclusion: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Mathematical induction lowered via the canonical IR formalizer at compile time.

Source code in gaia/engine/lang/dsl/strategies.py
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
def mathematical_induction(
    base: Knowledge,
    step: Knowledge,
    conclusion: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Mathematical induction lowered via the canonical IR formalizer at compile time."""
    return _named_strategy(
        "mathematical_induction",
        premises=[base, step],
        conclusion=conclusion,
        background=background,
        reason=reason,
    )

noisy_and

noisy_and(premises: list[Knowledge], conclusion: Knowledge, *, background: list[Knowledge] | None = None, reason: ReasonInput = '') -> Strategy

Deprecated compatibility wrapper for old noisy-and packages.

Source code in gaia/engine/lang/dsl/strategies.py
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
def noisy_and(
    premises: list[Knowledge],
    conclusion: Knowledge,
    *,
    background: list[Knowledge] | None = None,
    reason: ReasonInput = "",
) -> Strategy:
    """Deprecated compatibility wrapper for old noisy-and packages."""
    warnings.warn(
        "noisy_and() is deprecated for v0.5+ authoring; use derive() for "
        "deterministic reasoning or infer()/bayes.compare() for "
        "probabilistic evidence links.",
        DeprecationWarning,
        stacklevel=2,
    )
    # noisy_and is deprecated and doesn't support the prior parameter.
    # Bypass support() to avoid reason+prior pairing validation.
    if len(premises) < 1:
        raise ValueError("support() requires at least 1 premise")
    return _named_strategy(
        "support",
        premises=premises,
        conclusion=conclusion,
        background=background,
        reason=reason,
        metadata={},
    )

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

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,
    )

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

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

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