Component#

Layer 4: Extend Framework

最適化の処理を実行するコンポーネントは、実行内容と静的な契約を分けて扱います。 Component Protocolは、そのコンポーネントがComponentContractを返す境界だけを定めます。

Componentの役割#

Componentは、実行内容と静的な契約の境界を所有します。 Component Protocolが定めるのは、コンパイル時にComponentContractを返す責務だけであり、ポート互換性や状態ストアの更新は担当しません。

Component Protocolとcontract()#

Componentはcontract() -> ComponentContractを提供します。 contract()はコンパイル時に読み取る純粋な契約のスナップショットを返し、実行中の可変状態を返す場所ではありません。

Component Protocol自体はexecute()を定義しません。 Graph-nativeの実行コンポーネントがexecute(StateView)を提供することは、Runtimeが利用する別の実行境界です。

ComponentContractはComponentの基底クラスでも派生型でもありません。 Componentがコンポーネントを保持する場合、各コンポーネントの契約をPartSpecとして親契約に包含します。

from saealib.core import Component, ComponentContract


class Normalize(Component):
    def contract(self) -> ComponentContract:
        return ComponentContract()

この例はProtocolの最小境界だけを示します。実際の入力、出力、状態、サービスはComponentContractとSpecsで宣言します。

PartSpecの包含#

PartSpecは、Componentがコンストラクターなどで保持する別のComponentの契約を名前付きで宣言します。 親Componentは子Componentを継承するのではなく、partsに子の契約を含めます。 optional=Trueは、そのコンポーネントが構成上省略可能であることを表します。

この包含により、Compilerは親のポートや状態効果と、保持コンポーネントの契約を同じ計画上で検証できます。 実行時のコンポーネントインスタンスの所有者はComponentであり、契約の不変性はComponentContractが担保します。

生成時点と利用時点#

ComponentのインスタンスはGraph構築時にComponentNodeへ配置されます。 Compilerはコンパイル開始時にcontract()を読み取り、同じコンパイルの解決と検証ではそのスナップショットを使います。 Runtimeは契約を再解釈せず、ExecutablePlanが指定したポート、サービス、状態境界を使います。

不変条件と診断#

Componentは任意のStateStoreを直接変更せず、宣言したStateKeyのStateViewを読み、StatePatchまたはNodeResultを返します。 Componentはポートの互換性を自分で決めず、接続後の判定をCompilerへ委譲します。 contract()がComponentContractを返さない場合、Graph構築またはCompilerの契約スナップショット取得でcontract_unavailable診断になります。

拡張点#

新しいComponentを作る最小の拡張は、contract()とRuntimeが利用する実行境界を実装し、必要な契約を返すことです。

関連ページ#

未宣言の状態アクセスやコンポーネント間の不整合は、Contract、Graph、Compilerの検証対象です。 拡張手順はフレームワーク拡張を、公開import経路はAPIリファレンスで確認してください。

参照#