Documentation

VerifiedMBSE.Behavior.ProductKripke

ProductKripke: Heterogeneous Product of Kripke Structures #

任意の [ToKripke α S₁ D₁][ToKripke β S₂ D₂] に対して、2 つの Kripke 構造の インタリーブ積 ProductKripke x y を定義する。本ファイルは StateMachine 非依存 で、純粋な Kripke 層の理論のみを扱う。

B-8 の中核 #

B-7 までは積状態機械 ProductStateMachine sm₁ sm₂ が第 1/2 引数とも StateMachine 特化であり、ProductStateMachine psm₁₂ sm₃ のように ProductKripke を入れ子に することができなかった(3 機以上のネスト合成不可能)。

B-8 では ProductKripke 型自体を 任意の ToKripke インスタンス型を受け取る ように一般化する。これにより:

が同じ API で書ける。旧 ProductStateMachine sm₁ sm₂ProductKripke sm₁ sm₂abbrev として Behavior/Product.lean で後方互換維持。

設計 #

ProductKripke x y は空構造体 #

型そのものが「x と y の積を考える」という合意を表現するマーカー。値は重要でなく ⟨⟩ で構築。将来メタデータ(同期遷移表、ラベル)追加の拡張点として構造体型を保持。

ProductKripkeReachable はインタリーブ積 #

各ステップは x 側または y 側のいずれか一方の step を消費し、相手側は不変。 同期遷移(両側同時)は扱わない。

inv の保存 #

ProductKripkeReachable 自体は inv 保存条件を持たない。代わりに、以下の 2 段階:

  1. fst_reachable / snd_reachable で「積到達可能 → 各成分の到達可能」を示す
  2. 各成分の reachable_invKripkeStructure のフィールド公理)を組み合わせて inv_holds を導く

これにより、stepinv 保存を直接要求する必要がなく、KripkeStructure の 定義が軽量に保たれる(Transition.preserves のような型レベル契約は要素側で持つ)。

structure VerifiedMBSE.Behavior.ProductKripke {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] (x : α) (y : β) :

任意の [ToKripke α S₁ D₁][ToKripke β S₂ D₂] に対する積マーカー型。

空構造体。値は ⟨⟩ で構築。型レベルで「x と y の積を考える」という合意のみを 表現し、意味論は ProductKripkeReachable / ProductKripke.toKripke で与える。

明示的な mk :: コンストラクタを宣言することで、フィールドなし構造体でも Lean のパーサが次の宣言を正しく読めるようにする。

    Instances For
      inductive VerifiedMBSE.Behavior.ProductKripkeReachable {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] (x : α) (y : β) :
      S₁ × S₂D₁ × D₂Prop

      積 Kripke 構造の到達可能性。インタリーブ積として定義する。

      • init: 両側の Kripke 構造が到達可能な点 (s₁, d₁) / (s₂, d₂) から スタート。旧 ProductReachable.init は StateMachine の初期状態に縛られていたが、 新版は任意の reachable 点から出発できるため、fromLeft / fromRight の 証明が induction 不要になる。
      • stepLeft / stepRight: 左/右の (toKripke x/y).step を 1 ステップ進め、 相手側は不変。
      Instances For
        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.fst_reachable {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} {p : S₁ × S₂} {d : D₁ × D₂} (h : ProductKripkeReachable x y p d) :

        射影: 積の到達可能性から左成分の到達可能性を取り出す。

        stepLeft ケースでは要素側 KripkeStructurestep_preserves_reachable 公理を使い、stepRight ケースでは左成分が変化しないので IH をそのまま返す。

        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.snd_reachable {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} {p : S₁ × S₂} {d : D₁ × D₂} (h : ProductKripkeReachable x y p d) :

        射影: 積の到達可能性から右成分の到達可能性を取り出す。

        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.inv_holds {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} {p : S₁ × S₂} {d : D₁ × D₂} (h : ProductKripkeReachable x y p d) :

        積の安全性定理: 積到達可能なら両成分の inv を満たす。

        fst_reachable / snd_reachable で各成分の reachable を取り出し、 要素側 KripkeStructurereachable_inv 公理を適用するだけ。 ProductKripkeReachable 自体の induction は不要。

        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.step_preserves_reachable {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} (p : S₁ × S₂) (d : D₁ × D₂) (p' : S₁ × S₂) (d' : D₁ × D₂) :
        ProductKripkeReachable x y p d(ToKripke.toKripke x).step p.fst d.fst p'.fst d'.fst p.snd = p'.snd d.snd = d'.snd (ToKripke.toKripke y).step p.snd d.snd p'.snd d'.snd p.fst = p'.fst d.fst = d'.fstProductKripkeReachable x y p' d'

        積の step が到達可能性を保存する。

        ProductKripke.toKripkestep_preserves_reachable フィールドに渡す補題。 インタリーブの disjunction を分解し、各枝で stepLeft / stepRight コンストラクタを 適用する。

        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.fromLeft {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} {s₁ : S₁} {d₁ : D₁} (hr₁ : (ToKripke.toKripke x).reachable s₁ d₁) (hne₂ : (ToKripke.toKripke y).NonEmpty) :
        (s₂ : S₂), (d₂ : D₂), ProductKripkeReachable x y (s₁, s₂) (d₁, d₂)

        持ち上げ: 左側 Kripke 構造の reachable 点から、相手側の NonEmpty を補って 積の到達可能性を構成する。

        ProductReachable.fromLeft は StateMachine の WellFormed を要求し induction が必要だったが、新 ProductKripkeReachable.init が任意の reachable 点から 始められるため、init コンストラクタ一発で証明が済む。

        theorem VerifiedMBSE.Behavior.ProductKripkeReachable.fromRight {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} {s₂ : S₂} {d₂ : D₂} (hr₂ : (ToKripke.toKripke y).reachable s₂ d₂) (hne₁ : (ToKripke.toKripke x).NonEmpty) :
        (s₁ : S₁), (d₁ : D₁), ProductKripkeReachable x y (s₁, s₂) (d₁, d₂)

        持ち上げ: 右側 Kripke 構造の reachable 点から、相手側の NonEmpty を補って 積の到達可能性を構成する。

        @[reducible, inline]
        abbrev VerifiedMBSE.Behavior.ProductKripke.toKripke {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} :
        ProductKripke x yKripkeStructure (S₁ × S₂) (D₁ × D₂)

        ProductKripke x yKripkeStructure (S₁ × S₂) (D₁ × D₂) として見る。

        abbrev なので reducible で、以下の defeq 関係が成立する:

        • (pk.toKripke).inv p d = (toKripke x).inv p.1 d.1 ∧ (toKripke y).inv p.2 d.2
        • (pk.toKripke).reachable p d = ProductKripkeReachable x y p d
        • (pk.toKripke).step = インタリーブ disjunction

        reachable_inv / step_preserves_reachable #

        §4 / §5 で証明した ProductKripkeReachable.inv_holds / ProductKripkeReachable.step_preserves_reachable をそのまま代入する。

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For
          @[implicit_reducible]
          instance VerifiedMBSE.Behavior.instToKripkeProductKripke {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} :
          ToKripke (ProductKripke x y) (S₁ × S₂) (D₁ × D₂)

          ProductKripke x y に対する ToKripke instance。

          これにより Always pk P / Eventually pk P / Leads pk P QStateMachine / ProductStateMachine と同一 API で書ける。 3 機以上のネスト合成 (ProductKripke (pk : ProductKripke ...) sm₃) も、 この instance が再帰的に resolve されて機能する。

          Equations
          theorem VerifiedMBSE.Behavior.ProductKripke.nonEmpty {α β S₁ D₁ S₂ D₂ : Type} [ToKripke α S₁ D₁] [ToKripke β S₂ D₂] {x : α} {y : β} (pk : ProductKripke x y) (hne₁ : (ToKripke.toKripke x).NonEmpty) (hne₂ : (ToKripke.toKripke y).NonEmpty) :

          両側の NonEmpty から、積の NonEmpty を導く。

          init コンストラクタで両側の reachable 点から積到達可能状態を構築できるため、 induction 不要の自明な証明。