Skip to content

Facts & propositions (guardrail_calculus.facts)

Propositions and the type-level chain of labelled checks shared by the builder surface and the reasoning layer.

facts

Propositions and the typed check chain.

Prop wraps a boolean expression with optional human text; Check, Nil, and Snoc form the type-level list of labelled checks accumulated by subject builders, and SubjectFacts is the sealed block a subject contributes to a puzzle.

Shared by the builder surface and the reasoning layer; imports only the kernel and the dimensions module, so it stays cycle-free.

ExprT module-attribute

ExprT = TypeVar('ExprT')

PropT module-attribute

PropT = TypeVar('PropT', bound=Prop)

BoolishT module-attribute

BoolishT = TypeVar('BoolishT', bound=Boolish_Bound)

Given_Bound module-attribute

Given_Bound = Prop[Any] | None

Prop dataclass

Bases: Generic[ExprT]

A proposition: a boolean expression plus optional human-facing text.

Prop is what .given(...) and .check(...) store. text is the sentence shown in explanations; when omitted it falls back to the expression's own label. bind re-roots the proxy _ to a concrete subject during ingestion.

Attributes:

Name Type Description
expr ExprT

The underlying expression (e.g., a BoolExpr).

text str | None

Human-facing description of the proposition.

Examples:

>>> from guardrail_calculus.facts import Prop
>>> p = Prop(True, "My Premise")
>>> p.display_text
'My Premise'
Source code in src/guardrail_calculus/facts.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
71
72
73
74
75
76
@dataclass(frozen=True)
class Prop(Generic[ExprT]):
    """A proposition: a boolean expression plus optional human-facing text.

    [Prop][guardrail_calculus.facts.Prop] is what `.given(...)` and `.check(...)` store.
    `text` is the sentence shown in explanations; when omitted it falls back to the
    expression's own label. `bind` re-roots the proxy `_` to a concrete subject during ingestion.

    Attributes:
        expr: The underlying expression (e.g., a [BoolExpr][guardrail_kernel.expressions.BoolExpr]).
        text: Human-facing description of the proposition.

    Examples:
        >>> from guardrail_calculus.facts import Prop
        >>> p = Prop(True, "My Premise")
        >>> p.display_text
        'My Premise'
    """

    expr: ExprT
    text: str | None = None

    @property
    def display_text(self) -> str | None:
        if self.text is not None:
            return self.text

        if is_bool_like(self.expr):
            return self.expr.label

        return None

    def bind(self, subject_name: str) -> Prop[BoolExpr[Any]]:
        if not isinstance(self.expr, BoolExpr):
            raise TypeError(f"Only BoolExpr props can be bound, got {self.expr!r}")

        return Prop(
            expr=bind_bool_expr(self.expr, subject_name=subject_name),
            text=self.text,
        )

expr instance-attribute

expr

text class-attribute instance-attribute

text = None

display_text property

display_text

bind

bind(subject_name)
Source code in src/guardrail_calculus/facts.py
69
70
71
72
73
74
75
76
def bind(self, subject_name: str) -> Prop[BoolExpr[Any]]:
    if not isinstance(self.expr, BoolExpr):
        raise TypeError(f"Only BoolExpr props can be bound, got {self.expr!r}")

    return Prop(
        expr=bind_bool_expr(self.expr, subject_name=subject_name),
        text=self.text,
    )

ChecksLike

Bases: Protocol

Structural protocol for the type-level check chain.

Implemented by Nil and Snoc.

Source code in src/guardrail_calculus/facts.py
114
115
116
117
118
119
120
class ChecksLike(Protocol):
    """Structural protocol for the type-level check chain.

    Implemented by [Nil][guardrail_calculus.facts.Nil] and [Snoc][guardrail_calculus.facts.Snoc].
    """

    def items(self) -> Iterable[tuple[str, Prop[Any]]]: ...

items

items()
Source code in src/guardrail_calculus/facts.py
120
def items(self) -> Iterable[tuple[str, Prop[Any]]]: ...

Check dataclass

A single labelled candidate proposition, e.g. check "A" over a prop.

The label is kept in the type (LabelT) so a solved puzzle can be indexed by literal label with the result type preserved.

Attributes:

Name Type Description
label LabelT

The literal string label identifying the check.

prop PropT

The checked Prop proposition.

Examples:

>>> from guardrail_calculus.facts import Check, Prop
>>> c = Check("A", Prop(True))
>>> c.label
'A'
Source code in src/guardrail_calculus/facts.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
@dataclass(frozen=True)
class Check[LabelT: str, PropT: Prop[Any]]:
    """A single labelled candidate proposition, e.g. check `"A"` over a prop.

    The label is kept in the type (`LabelT`) so a solved puzzle can be indexed
    by literal label with the result type preserved.

    Attributes:
        label: The literal string label identifying the check.
        prop: The checked [Prop][guardrail_calculus.facts.Prop] proposition.

    Examples:
        >>> from guardrail_calculus.facts import Check, Prop
        >>> c = Check("A", Prop(True))
        >>> c.label
        'A'
    """

    label: LabelT
    prop: PropT

label instance-attribute

label

prop instance-attribute

prop

Nil dataclass

The empty check chain (cons-list base case).

See Snoc for the recursive case.

Examples:

>>> from guardrail_calculus.facts import Nil
>>> list(Nil().items())
[]
Source code in src/guardrail_calculus/facts.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
@dataclass(frozen=True)
class Nil:
    """The empty check chain (cons-list base case).

    See [Snoc][guardrail_calculus.facts.Snoc] for the recursive case.

    Examples:
        >>> from guardrail_calculus.facts import Nil
        >>> list(Nil().items())
        []
    """

    def items(self) -> Iterable[tuple[str, Prop[Any]]]:
        return ()

items

items()
Source code in src/guardrail_calculus/facts.py
161
162
def items(self) -> Iterable[tuple[str, Prop[Any]]]:
    return ()

Snoc dataclass

A check chain: everything in init followed by one more last.

Builders accumulate checks by snoc-ing, so the full sequence of labels and props is recoverable both at runtime (items) and in the static type.

Attributes:

Name Type Description
init InitT

The preceding part of the check chain.

last LastT

The last Check added to the chain.

Examples:

>>> from guardrail_calculus.facts import Nil, Check, Prop, Snoc
>>> chain = Snoc(Nil(), Check("A", Prop(True)))
>>> tuple(label for label, _ in chain.items())
('A',)
Source code in src/guardrail_calculus/facts.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
@dataclass(frozen=True)
class Snoc[InitT: ChecksLike, LastT: Check[Any, Any]]:
    """A check chain: everything in `init` followed by one more `last`.

    Builders accumulate checks by snoc-ing, so the full sequence of labels and
    props is recoverable both at runtime (`items`) and in the static type.

    Attributes:
        init: The preceding part of the check chain.
        last: The last [Check][guardrail_calculus.facts.Check] added to the chain.

    Examples:
        >>> from guardrail_calculus.facts import Nil, Check, Prop, Snoc
        >>> chain = Snoc(Nil(), Check("A", Prop(True)))
        >>> tuple(label for label, _ in chain.items())
        ('A',)
    """

    init: InitT
    last: LastT

    def items(self) -> Iterable[tuple[str, Prop[Any]]]:
        yield from self.init.items()
        yield self.last.label, self.last.prop

init instance-attribute

init

last instance-attribute

last

items

items()
Source code in src/guardrail_calculus/facts.py
186
187
188
def items(self) -> Iterable[tuple[str, Prop[Any]]]:
    yield from self.init.items()
    yield self.last.label, self.last.prop

SubjectFacts dataclass

The sealed block one subject contributes to a puzzle.

Produced by subject()...block(). given is the subject's premise (if any), checks is its type-level chain of candidate propositions, and own is the self-reference used inside the block.

Attributes:

Name Type Description
own OwnT

The self-reference proxy for this subject.

given GivenT

The subject's premise/given premise.

checks ChecksT

The chain of checks to be validated.

Examples:

>>> from guardrail_calculus.facts import SubjectFacts, Nil
>>> block = SubjectFacts(own="my_subject", given=None, checks=Nil())
>>> block.own
'my_subject'
Source code in src/guardrail_calculus/facts.py
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
@dataclass(frozen=True)
class SubjectFacts[
    GivenT: Given_Bound = None,
    ChecksT: ChecksLike = Nil,
    OwnT = Any,
]:
    """The sealed block one subject contributes to a puzzle.

    Produced by `subject()...block()`. `given` is the subject's premise (if
    any), `checks` is its type-level chain of candidate propositions, and
    `own` is the self-reference used inside the block.

    Attributes:
        own: The self-reference proxy for this subject.
        given: The subject's premise/given premise.
        checks: The chain of checks to be validated.

    Examples:
        >>> from guardrail_calculus.facts import SubjectFacts, Nil
        >>> block = SubjectFacts(own="my_subject", given=None, checks=Nil())
        >>> block.own
        'my_subject'
    """

    own: OwnT
    given: GivenT
    checks: ChecksT
    _z3_dim: Literal["subject"] = field(
        default="subject",
        init=False,
        repr=False,
        compare=False,
    )

own instance-attribute

own

given instance-attribute

given

checks instance-attribute

checks

prop

prop(value: Prop[ExprT]) -> Prop[ExprT]
prop(value: ExprT) -> Prop[ExprT]
prop(value)

Coerce a boolean expression (or an existing Prop) into a Prop.

Parameters:

Name Type Description Default
value Boolish_Bound | Prop[Any]

The expression or existing proposition to coerce.

required

Returns:

Type Description
Prop[Any]

A coerced Prop container.

Examples:

>>> from guardrail_calculus.facts import prop
>>> p = prop(True)
>>> p.expr
True
Source code in src/guardrail_calculus/facts.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def prop(value: Boolish_Bound | Prop[Any]) -> Prop[Any]:
    """Coerce a boolean expression (or an existing [Prop][guardrail_calculus.facts.Prop]) into a [Prop][guardrail_calculus.facts.Prop].

    Args:
        value: The expression or existing proposition to coerce.

    Returns:
        A coerced [Prop][guardrail_calculus.facts.Prop] container.

    Examples:
        >>> from guardrail_calculus.facts import prop

        >>> p = prop(True)

        >>> p.expr
        True
    """
    if isinstance(value, Prop):
        return value

    return Prop(expr=value)