Traces of multiple global steps

Traces

We consider traces of the (global) step relation, defined as its reflexive-transitive closure, and use these to prove invariants as state predicates:

open import Prelude.Closures _—→_ public
  using ( begin_; _∎ ; _↞—_; _⟨_⟩←—_; _⟨_∣_⟩←—_; ↞—-trans
        ; _—↠_; —↠-trans; _—→⟨_⟩_; _—→⟨_∣_⟩_; _`—→⟨_⟩_; factor; factor⁺; Reachable-inj
        ; Reachable; Invariant; StepPreserved; Step⇒Invariant
        ; Trace; TraceProperty; TraceInvariant
        ; viewLeft; viewRight; viewLeft∘viewRight
        ; states⁺; states; states⁺-↞—; states-↞—; states⁺∘viewLeft
        )
  renaming (_←—_ to _¹←—_)

StateProperty = GlobalState  Type

Now, we can consider a specific local step occurring within a sequence of global transitions:

record Step : Type where
  constructor _⊢_
  field
    stepArgs : _ × _ × _ × _ × _
    theStep  : let p , t , ls , menv , ls′ = stepArgs in
               p  t  ls  menv —→ ls′
     hp  : Honest (stepArgs .proj₁)
open Step public
  hiding (hp)

-- doStep : Step → Op₁ GlobalState
-- doStep st s = let p , _ , _ , menv , ls′ = st .stepArgs in
--   broadcast menv (s @ p ≔ ls′)

LocalStepProperty = Step  Type

allLocalSteps : (s′ ↞— s)  List Step
allLocalSteps = λ where
  (_ )  []
  (_  LocalStep st ⟩←— tr)  (_  st)  allLocalSteps tr
  (_  _ ⟩←— tr)  allLocalSteps tr

_∋⋯_ : Reachable s  LocalStepProperty  Type
(_ , _ , tr) ∋⋯ P = Any P (allLocalSteps tr)

record Segment (A B : Type) : Type where
  constructor from_to_
  field _∙start _∙end : B  A
open Segment ⦃...⦄ public

instance
  Segment-↞ : Segment GlobalState (s′ ↞— s)
  Segment-↞ {s′}{s} = from (const s) to (const s′)

  Segment-→ : Segment LocalState (p  t  ls  menv —→ ls′)
  Segment-→ {ls = ls} {ls′ = ls′} = from (const ls) to (const ls′)

  Segment-Step : Segment LocalState Step
  Segment-Step = from (_∙start  theStep) to (_∙end  theStep)
extendRs : (Rs : Reachable s)  s′ ↞— s  Reachable s′
extendRs (_ , init , tr) tr′ = _ , init , ↞—-trans tr′ tr

_▷_ : GlobalState  LocalStepProperty  Type
s  P =  λ st 
          let p , t , ls , _ , _ = stepArgs st in
            t  s .currentTime
          × s  p  ls
          × P st

▷-doStep :  {P}  s  P  GlobalState
▷-doStep {s = s} (st , _) = let p , t , _ , menv , ls′ = st .stepArgs in
  broadcast t menv (s  p  ls′)

_◃_ : LocalStepProperty  GlobalState  Type
P  s′ =  λ st   λ s 
          let p , t , ls , menv , ls′ = stepArgs st in
            t  s .currentTime
          × s  p  ls
          × s′  broadcast t menv (s  p  ls′)
          × P st

record TraceExtension (Rs : Reachable s) : Type where
  constructor ⟨_,_,_,_⟩
  field
    intState   : GlobalState
    reachable′ : Reachable intState
    extension  : s ↞— intState
    traceAgree : Rs  extendRs reachable′ extension
open TraceExtension

traceRs◃ :   (Rs : Reachable s){P} 
  (trP : Rs ∋⋯ P) 
  ────────────────────────────────────────────────
  Σ (TraceExtension Rs)  trE  P  intState trE)
traceRs◃ (_ , init , (s  Deliver tpm∈ ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs◃ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  Deliver tpm∈ ⟩←— tr⟪) , refl  , p
traceRs◃ Rs@(_ , init , tr@(s′  LocalStep st  s ⟩←— _)) (here px)
 =    s′ , Rs , s′  , refl  , ( _  st) , s , refl , refl , refl , px
traceRs◃ (_ , init , (s  LocalStep st ⟩←— tr)) (there trP)
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs◃ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  LocalStep st ⟩←— tr⟪) , refl  , p
traceRs◃ (_ , init , (s  DishonestLocalStep {env = env} ¬hp st ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs◃ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  DishonestLocalStep {env = env} ¬hp st ⟩←— tr⟪) , refl  , p
traceRs◃ (_ , init , (s  WaitUntil t  now≤t ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs◃ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  WaitUntil t  now≤t ⟩←— tr⟪) , refl  , p

traceRs▷ :   (Rs : Reachable s){P} 
  (trP : Rs ∋⋯ P) 
  ────────────────────────────────────────────────
  Σ (TraceExtension Rs)  trE  intState trE  P)
traceRs▷ (_ , init , (s  Deliver tpm∈ ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs▷ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  Deliver tpm∈ ⟩←— tr⟪) , refl  , p
traceRs▷ (_ , init , (s′  LocalStep st  s ⟩←— tr)) (here px)   =
   s , (_ , init , tr) , (s′  LocalStep st ⟩←— s ) , refl  , ( _  st) , refl , refl , px
traceRs▷ (_ , init , (s  LocalStep st     ⟩←— tr)) (there trP)
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs▷ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  LocalStep st ⟩←— tr⟪) , refl  , p
traceRs▷ (_ , init , (s  DishonestLocalStep {env = env} ¬hp st ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs▷ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  DishonestLocalStep {env = env} ¬hp st ⟩←— tr⟪) , refl  , p
traceRs▷ (_ , init , (s  WaitUntil t  now≤t ⟩←— tr)) trP
  with  s⟪ , Rs⟪ , tr⟪ , refl  , ptraceRs▷ (_ , init , tr) trP
  =  s⟪ , Rs⟪ , (s  WaitUntil t  now≤t ⟩←— tr⟪) , refl  , p

-- TODO: traceRs ⇒ non-empty extension (traceRs⁺)

-- _≺_ : S → S → Type where
--   ∼ non-reflexive transitive closure
--
--   s′ ⁺↞— s
--   ────────
--   s ≺ s′

-- eventually: ≺-rec (traceRs⁺ st-proposes) Rs′ ...

∃→ : Type
∃→ =  λ s   λ s′  s —→ s′

data IsLocal : ∃→  Type where
  LocalStep :   _ : Honest p  {st : p  s .currentTime  s  p  menv —→ ls′} 
    IsLocal (s , -, LocalStep st)

record _ᴸ←—_ (s′ s : GlobalState) : Type where
  constructor _⊣ᴸ_
  field {_p _menv _ls′} : _
         hp  : Honest _p
  _ls  = s  _p
  field localStep : _p  s .currentTime  _ls  _menv —→ _ls′
        s≡        : s′  broadcast (s .currentTime) _menv (s  _p  _ls′)

open _ᴸ←—_

instance
  Dec-IsLocal : IsLocal ⁇¹
  Dec-IsLocal {_ , _ , st} .dec with st
  ... | LocalStep _            = yes LocalStep
  ... | DishonestLocalStep _ _ = no λ ()
  ... | Deliver _              = no λ ()
  ... | WaitUntil _ _ _        = no λ ()

Local→Global : s′ ᴸ←— s  s′ ¹←— s
Local→Global st
  = subst (_¹←— _) (sym $ st .s≡)
  $ LocalStep (st . localStep)

Local→Global⇒IsLocal :  {st : s′ ᴸ←— s} 
  IsLocal (-, -, Local→Global st)
Local→Global⇒IsLocal {st = _ ⊣ᴸ refl} = LocalStep

record ∃IsLocal : Type where
  constructor _,_
  field stl : ∃→
        .loc : IsLocal stl

∃IsLocal≡ :  {r r′} 
  r .∃IsLocal.stl  r′ .∃IsLocal.stl
  ──────────────────
  r  r′
∃IsLocal≡ refl = refl

module _ (r : ∃IsLocal) (let stl , loc = r) where
  getLoc : IsLocal stl
  getLoc = recompute dec loc

  getP : Pid
  getP with stl | getLoc
  ... | _ , _ , LocalStep {p = p} _ | LocalStep = p

  getM : Maybe Envelope
  getM with stl | getLoc
  ... | _ , _ , LocalStep {menv = menv} _ | LocalStep = menv

  getL : LocalState
  getL with stl | getLoc
  ... | _ , _ , LocalStep {ls′ = ls′} _ | LocalStep = ls′

getP≡ :  (st : s′ ᴸ←— s) 
  getP ((-, -, Local→Global st) , Local→Global⇒IsLocal)  st ._p
getP≡ (_ ⊣ᴸ refl) = refl

getM≡ :  (st : s′ ᴸ←— s) 
  getM ((-, -, Local→Global st) , Local→Global⇒IsLocal)  st ._menv
getM≡ (_ ⊣ᴸ refl) = refl

getL≡ :  (st : s′ ᴸ←— s) 
  getL ((-, -, Local→Global st) , Local→Global⇒IsLocal)  st ._ls′
getL≡ (_ ⊣ᴸ refl) = refl

Local→Global-inj :  (st st′ : s′ ᴸ←— s) 
  Local→Global st  Local→Global st′
  ──────────────────────────────────
  st  st′
Local→Global-inj {s′}{s} st@(_ ⊣ᴸ s≡) st′@(_ ⊣ᴸ s≡′) st≡ = QED
  where
  ∃st ∃st′ : ∃→
  ∃st  = -, -, Local→Global st
  ∃st′ = -, -, Local→Global st′

  ∃st≡ : ∃st  ∃st′
  ∃st≡ = cong    s , s′ , ) st≡

  ∃stl ∃stl′ : ∃IsLocal
  ∃stl  = ∃st  , Local→Global⇒IsLocal
  ∃stl′ = ∃st′ , Local→Global⇒IsLocal

  ∃stl≡ : ∃stl  ∃stl′
  ∃stl≡ = ∃IsLocal≡ ∃st≡

  p≡ : st ._p  st′ ._p
  p≡ = subst (_≡ _) (getP≡ st) $ subst (_ ≡_) (getP≡ st′)
     $ cong getP ∃stl≡

  m≡ : st ._menv  st′ ._menv
  m≡ = subst (_≡ _) (getM≡ st) $ subst (_ ≡_) (getM≡ st′)
     $ cong getM ∃stl≡

  l≡ : st ._ls′  st′ ._ls′
  l≡ = subst (_≡ _) (getL≡ st) $ subst (_ ≡_) (getL≡ st′)
     $ cong getL ∃stl≡

  QED : st  st′
  QED with st ._p  st′ ._p
  ... | no p≢ = ⊥-elim $ p≢ p≡
  ... | yes refl with st ._menv  st′ ._menv
  ... | no m≢ = ⊥-elim $ m≢ m≡
  ... | yes refl with st ._ls′  st′ ._ls′
  ... | no l≢ = ⊥-elim $ l≢ l≡
  ... | yes refl with  s≡ |  s≡′ |  st≡
  ... |  refl |  refl |  refl = refl

_⟨_⟩←—ᴿ_ :  s′  s′ ¹←— s  Reachable s  Reachable s′
_  st ⟩←—ᴿ (_ , s-init , tr) =
  (_ , s-init , (_  st ⟩←— tr))

record TraceExtension⁺ {z} (Rz : Reachable z) : Type where
  constructor ⟨_,_,_,_⟩
  field
    {x y} : GlobalState
    Rx    : Reachable x
    y←x   : y ᴸ←— x
    z↞y   : z ↞— y

  y¹←x : y ¹←— x
  y¹←x = Local→Global y←x

  z↞x : z ↞— x
  z↞x = _ `—→⟨ y¹←x  z↞y

  Ry : Reachable y
  Ry = _  y¹←x ⟩←—ᴿ Rx

  field
    Rz≡ : Rz  extendRs Ry z↞y
    -- Rz≡ : Rz ≡ extendRs Rx z↞x

  step : Step
  step = _  y←x ._ᴸ←—_.localStep

open TraceExtension⁺

private
  UIP : (p q : s  s′)  p  q
  UIP refl refl = refl

  open Prod hiding (,-injectiveʳ)

step≡-TE⁺ :  {s} (Rs : Reachable s) (trE trE′ : TraceExtension⁺ Rs) 
  _≡_ {A =  λ x   λ y  y ¹←— x} (-, -, y¹←x trE) (-, -, y¹←x trE′)
  ────────────────────────────────────────────────────────────────────
  step trE  step trE′
step≡-TE⁺ Rs trE trE′ eq
  with refl,-injectiveˡ eq
  with refl,-injectiveˡ $ ,-injectiveʳ-≡ UIP eq refl
  with eq′,-injectiveʳ-≡ UIP (,-injectiveʳ-≡ UIP eq refl) refl
  with reflLocal→Global-inj _ _ eq′
  = refl

traceRs⁺ :  (Rs : Reachable s) {P} 
  (trP : Rs ∋⋯ P) 
  ────────────────────────────────
  Σ (TraceExtension⁺ Rs) (P  TraceExtension⁺.step)
traceRs⁺ (_ , init , (s  Deliver tpm∈ ⟩←— tr)) trP
  with  s , Rs , tr , refl  , PtraceRs⁺ (_ , init , tr) trP
     =  s , Rs , (_  Deliver tpm∈ ⟩←— tr) , refl  , P
traceRs⁺ (_ , init , (s′  LocalStep st  s ⟩←— tr)) (here px)
 =  (_ , init , tr) , (st ⊣ᴸ refl) , (s′ ) , refl  , px
traceRs⁺ (_ , init , (_  LocalStep  st ⟩←— tr)) (there trP)
  with  s , Rs , tr , refl  , PtraceRs⁺ (_ , init , tr) trP
     =  s , Rs , (_  LocalStep st ⟩←— tr) , refl  , P
traceRs⁺ (_ , init , (_  DishonestLocalStep {env = env} ¬hp st ⟩←— tr)) trP
  with  s , Rs , tr , refl  , PtraceRs⁺ (_ , init , tr) trP
     =  s , Rs , (_  DishonestLocalStep {env = env} ¬hp st ⟩←— tr) , refl  , P
traceRs⁺ (_ , init , (_  WaitUntil t  now≤t ⟩←— tr)) trP
  with  s , Rs , tr , refl  , PtraceRs⁺ (_ , init , tr) trP
     =  s , Rs , (_  WaitUntil t  now≤t ⟩←— tr) , refl  , P

{-
TraceExtension⁺⁻ : ∀ {Rs : Reachable s} → TraceExtension⁺ Rs → TraceExtension Rs
TraceExtension⁺⁻ tr@(⟨ Rs , st , sts , refl ⟩) =
  ⟨ tr .x , Rs , _ `—→⟨ Local→Global st ⟩ sts  , refl ⟩

TraceExtension⁺⁻⁺ : ∀ {Rs : Reachable s} → TraceExtension⁺ Rs → TraceExtension Rs
TraceExtension⁺⁻⁺ tr@(⟨ Rs , st@(_ ⊣ᴸ eq) , sts , refl ⟩) =
  ⟨ tr .y , _ ⟨ Local→Global st ⟩←—ᴿ Rs , sts  , {!refl!} ⟩
-}

factorRs :  (Rs : Reachable s)
  (trE₁ trE₂ : TraceExtension Rs) 
  ─────────────────────────────────────
  let s₁ = trE₁ .intState
      s₂ = trE₂ .intState
  in (s₁ ↞— s₂)  (s₂ ↞— s₁)
factorRs Rs
   s₁ , (_ , _ , tr₁) , ext₁ , refl 
   s₂ , (_ , _ , tr₂) , ext₂ , eq₂ 
  with reflcong proj₁ eq₂
  = factor tr₁ ext₁ tr₂ ext₂ (Reachable-inj eq₂)

open import Data.Product.Properties.WithK using (,-injectiveʳ)

factorRs⁺ :  (Rs : Reachable s)  let open TraceExtension⁺ in
  (tr tr′ : TraceExtension⁺ Rs) 
  ────────────────────────────
    (step tr  step tr′)
   (tr′ .x ↞— tr  .y)
   (tr  .x ↞— tr′ .y)
factorRs⁺ Rs
  trE@( (_ , init , tr)  , (st  ⊣ᴸ refl) , st∗  , refl )
  trE′@( (_ , _   , tr′) , (st′ ⊣ᴸ refl) , st∗′ , eq₃ )
  with reflcong proj₁ eq₃
  with reflcong proj₁ $ ,-injectiveʳ eq₃
  with eq,-injectiveʳ  $ ,-injectiveʳ eq₃
  with factor⁺ tr (y¹←x trE) st∗ tr′ (y¹←x trE′) st∗′
               (Reachable-inj $ cong (_ ,_) $ cong (init ,_) eq)
... | inj₁ st≡      = inj₁ $ step≡-TE⁺ Rs trE trE′ st≡
... | inj₂ (inj₁ P) = inj₂ $ inj₂ P
... | inj₂ (inj₂ P) = inj₂ $ inj₁ P