File size: 6,323 Bytes
756f45d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 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 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 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 | module ControlFlowInvariants where
open import Relation.Binary.PropositionalEquality using (_β‘_; refl)
open import Data.Product using (_Γ_; _,_; projβ; projβ)
-- ============================================================
-- Abstract types for the ICP state machine architecture
-- ============================================================
postulate
Label : Set -- node identifiers in the ^ICP DAG
State : Set -- contents of ^ICP globals (memory/environment)
-- ============================================================
-- Control transfer primitives β structural duals
-- ============================================================
-- GOTO : push mechanics β L1 dictates the future by pushing to L2
-- COME-FROM : pull mechanics β L2 dictates the past by pulling from L1
data Transfer : Set where
GOTO : Label β Transfer
COME-FROM : Label β Transfer
-- A Program maps every Label to its outgoing Transfer
Prog = Label β Transfer
-- ============================================================
-- Operational semantics β the execution step relation
-- ============================================================
data Step (P : Prog) : Label Γ State β Label Γ State β Set where
-- PUSH INVARIANT: L1 actively pushes execution to L2.
-- State is passed through unchanged.
step-goto : β {lβ lβ s}
β P lβ β‘ GOTO lβ
------------------------------
β Step P (lβ , s) (lβ , s)
-- PULL INVARIANT: L2 actively pulls execution from L1.
-- State is passed through unchanged.
step-come-from : β {lβ lβ s}
β P lβ β‘ COME-FROM lβ
------------------------------
β Step P (lβ , s) (lβ , s)
-- ============================================================
-- INVARIANT 1: Strict State Preservation
--
-- Pure control-flow graph traversal guarantees the domain (State)
-- is unmutated across the topological shift.
-- This justifies the MUMPS PUSH/PULL routines passing STATE by value
-- and the ASP layer not touching ^ICP("NODE",...) data during traversal.
-- ============================================================
state-invariant : β {P lβ lβ sβ sβ}
β Step P (lβ , sβ) (lβ , sβ)
β sβ β‘ sβ
state-invariant (step-goto _) = refl
state-invariant (step-come-from _) = refl
-- ============================================================
-- INVARIANT 2: Control-Flow Duality
--
-- A GOTO edge is structurally isomorphic to a COME-FROM edge.
-- is-dual Pβ Pβ captures the bidirectional adjacency requirement
-- enforced by the ASP integrity constraints:
-- :- goto(L1,L2,Guard), not come_from(L2,L1,Guard).
-- :- come_from(L2,L1,Guard), not goto(L1,L2,Guard).
-- ============================================================
is-dual : Prog β Prog β Set
is-dual Pβ Pβ =
β lβ lβ
β (Pβ lβ β‘ GOTO lβ β Pβ lβ β‘ COME-FROM lβ)
Γ (Pβ lβ β‘ COME-FROM lβ β Pβ lβ β‘ GOTO lβ)
-- If Pβ has a GOTO step from (lβ,s) to (lβ,s),
-- then the dual program Pβ achieves the identical topological move
-- via COME-FROM β the same (Label Γ State) transition, different mechanics.
duality-invariant : β {Pβ Pβ lβ lβ s}
β is-dual Pβ Pβ
β Pβ lβ β‘ GOTO lβ
β Step Pβ (lβ , s) (lβ , s)
duality-invariant dual pβ-goto =
step-come-from (projβ (dual _ _) pβ-goto)
-- Symmetric: a COME-FROM step in Pβ corresponds to a GOTO step in Pβ.
duality-invariant-sym : β {Pβ Pβ lβ lβ s}
β is-dual Pβ Pβ
β Pβ lβ β‘ COME-FROM lβ
β Step Pβ (lβ , s) (lβ , s)
duality-invariant-sym dual pβ-come-from =
step-goto (projβ (dual _ _) pβ-come-from)
-- ============================================================
-- INVARIANT 3: Conditional Duality (Guard-tripartite edges)
--
-- When transitions are guarded, both GOTO and COME-FROM must
-- agree on the same guard. This is enforced by the ASP layer:
-- :- goto(L1,L2,Guard), not come_from(L2,L1,Guard).
-- Formalised here as a stronger is-dual over guarded programs.
-- ============================================================
postulate
Guard : Set -- guard conditions (evaluated against State)
-- A guarded transfer carries a condition
data GuardedTransfer : Set where
GOTO-IF : Label β Guard β GuardedTransfer
COME-FROM-IF : Label β Guard β GuardedTransfer
GuardedProg = Label β GuardedTransfer
-- Guarded step: transition fires only when guard matches
data GuardedStep (P : GuardedProg) (holds : Guard β State β Set)
: Label Γ State β Label Γ State β Set where
step-goto-guard : β {lβ lβ g s}
β P lβ β‘ GOTO-IF lβ g
β holds g s
β GuardedStep P holds (lβ , s) (lβ , s)
step-come-from-guard : β {lβ lβ g s}
β P lβ β‘ COME-FROM-IF lβ g
β holds g s
β GuardedStep P holds (lβ , s) (lβ , s)
-- Guarded duality: both programs must use the same guard on the same edge.
is-guarded-dual : GuardedProg β GuardedProg β Set
is-guarded-dual Pβ Pβ =
β lβ lβ g
β (Pβ lβ β‘ GOTO-IF lβ g β Pβ lβ β‘ COME-FROM-IF lβ g)
Γ (Pβ lβ β‘ COME-FROM-IF lβ g β Pβ lβ β‘ GOTO-IF lβ g)
-- Conditional duality invariant:
-- If Pβ fires a guarded GOTO under guard g at state s,
-- the dual Pβ fires the identical move via COME-FROM-IF with the same guard.
conditional-duality-invariant : β {Pβ Pβ holds lβ lβ g s}
β is-guarded-dual Pβ Pβ
β Pβ lβ β‘ GOTO-IF lβ g
β holds g s
β GuardedStep Pβ holds (lβ , s) (lβ , s)
conditional-duality-invariant dual pβ-goto-g hgs =
step-come-from-guard (projβ (dual _ _ _) pβ-goto-g) hgs
-- Determinism corollary (mirrors ASP constraint):
-- A state machine is deterministic iff at most one outgoing guarded edge holds.
is-deterministic : GuardedProg β (Guard β State β Set) β Set
is-deterministic P holds =
β lβ lβ lβ gβ gβ s
β P lβ β‘ GOTO-IF lβ gβ
β P lβ β‘ GOTO-IF lβ gβ
β holds gβ s
β holds gβ s
β lβ β‘ lβ
|