Invariants related to the global history.

VotesComplete : StateProperty
VotesComplete s =  {p b}  _ : Honest p  
  ─────────────────────────────────────────────
  votes ((s  p) .db) b ⊆ˢ votes (s .history) b

votesComplete : Invariant VotesComplete
votesComplete {s} Rs {p}{b} m∈? =
  let m∈ , b≡ = L.Mem.∈-filter⁻ ((b ≟_)  _∙block) m∈?
  in L.Mem.∈-filter⁺ ((b ≟_)  _∙block) (historyComplete Rs m∈) b≡

VoteIdsComplete : StateProperty
VoteIdsComplete s =  {p b}  _ : Honest p  
  ─────────────────────────────────────────────────
  voteIds ((s  p) .db) b ⊆ˢ voteIds (s .history) b

voteIdsComplete : Invariant VoteIdsComplete
voteIdsComplete Rs p∈
  with _ , m∈ , reflL.Mem.∈-map⁻ _∙pid p∈
  = L.Mem.∈-map⁺ _∙pid $ votesComplete Rs m∈

MessageSharing : StateProperty
MessageSharing s =  {p p′ b}  _ : Honest p   _ : Honest p′  
  p′  voteIds ((s  p)  .db) b
  ─────────────────────────────
  p′  voteIds ((s  p′) .db) b

messageSharing : Invariant MessageSharing
messageSharing {s} Rs {p}{p′}{b} p∈ =
  let
    m , m∈? , p≡ = L.Mem.∈-map⁻ _∙pid p∈
    m∈ , m≡  = L.Mem.∈-filter⁻ ((b ≟_)  _∙block) {xs = (s  p) .db} m∈?

    m∈′ : m  (s  p′) .db
    m∈′ = historySound Rs (historyComplete Rs m∈) p≡

    QED : p′  voteIds ((s  p′) .db) b
    QED = subst (_∈ _) (sym p≡)
        $ L.Mem.∈-map⁺ _∙pid
        $ L.Mem.∈-filter⁺ ((b ≟_)  _∙block) {xs = (s  p′) .db} m∈′ m≡
  in
    QED

Chain∈-Complete : StateProperty
Chain∈-Complete s =  {p ch}  _ : Honest p  
  ch chain-∈ (s  p) .db
  ──────────────────────
  ch chain-∈ s .history

chain∈-complete : Invariant Chain∈-Complete
chain∈-complete Rs = ⊆-ch∈ (historyComplete Rs)

NoFutureVotes≤ : StateProperty
NoFutureVotes≤ s =  {p b}  _ : Honest p  
  p  voteIds (s .history) b
  ──────────────────────────
  b .epoch  s .e-now

noFutureVotes≤ : Invariant NoFutureVotes≤
noFutureVotes≤ (_ , refl , (_ )) ()
noFutureVotes≤ {s′} (_ , refl , (_  s→  s ⟩←— tr))
  {p}{b} p∈
  with Rs-, refl , tr
  with IHnoFutureVotes≤ Rs {b = b}  it 
  with s→
... | Deliver _ = IH p∈
... | AdvanceEpoch = Nat.m≤n⇒m≤1+n $ IH p∈
... | Drop _ = IH p∈
... | LocalStep {p = p′}{mm}{ls′} ls→
  = QED
  where
  open ∣LocalStep∣ p p′ s mm ls′

  QED : b .epoch  s′ .e-now
  QED with  ls→
  QED |  ProposeBlock {ch = ch} {txs = txs} _ refl _ _
    with p  p′
  ... | no p≢ rewrite lookup✖ p≢
    = IH p∈′
    where
    p∈′ : p  voteIds (s .history) b
    p∈′ = voteIds-∷˘ {ms = s .history} (Eq.≢-sym p≢) p∈
  ... | yes refl rewrite lookup✓
    with b   ch  , s .e-now , txs 
  ... | yes refl = Nat.≤-refl
  ... | no  _    = IH p∈
  QED |  VoteBlock {H = H} {txs = txs} M∈ _ _ _ _ _
    with p  p′
  ... | no p≢ rewrite lookup✖ p≢
    = IH p∈′
    where
    p∈′ : p  voteIds (s .history) b
    p∈′ = voteIds-∷˘ {ms = s .history} (Eq.≢-sym p≢) p∈
  ... | yes refl rewrite lookup✓
    with b   H , s .e-now , txs 
  ... | yes refl = Nat.≤-refl
  ... | no  _    = IH p∈
  QED |  RegisterVote _ _ = IH p∈
  QED |  FinalizeBlock _ _ _ _ = IH p∈
... | DishonestLocalStep {p = p′}{m} ¬hp′ h⇒m∈
  = QED
  where
  QED : b .epoch  s′ .e-now
  QED with m ∙block  b
  ... | no b≢
    = IH $ voteIds-∷˘′ b≢ p∈
  ... | yes refl
    with m ∙pid  p
  ... | no p≢
    = IH $ voteIds-∷˘ {ms = s .history} p≢ p∈
  ... | yes refl
    = IH $ voteIds-accept∈ (h⇒m∈ it) refl refl

NoFutureVotes≢ : StateProperty
NoFutureVotes≢ s =  {p b}  _ : Honest p  
   p  voteIds (s .history) b
   (s  p) .phase  Ready
    ──────────────────────────
    b .epoch  s .e-now

noFutureVotes≢ : Invariant NoFutureVotes≢
noFutureVotes≢ (_ , refl , (_ )) ()
noFutureVotes≢ {s′} (_ , refl , (_  s→  s ⟩←— tr))
  {p}{b} p∈ ph≡
  with Rs-, refl , tr
  with IHnoFutureVotes≢ Rs {b = b}  it 
  with s→
... | Deliver {env = [ p′  m′ } env∈
  = IH p∈ $ subst (_≡ _) @ph≡ ph≡
  where
  open ∣Deliver∣ p s env∈
... | AdvanceEpoch
  = Nat.<⇒≢ $ Nat.s≤s QED
  where
  QED : b .epoch  s .e-now
  QED = noFutureVotes≤ Rs p∈
... | Drop _ = IH p∈ ph≡
... | LocalStep {p = p′}{mm}{ls′} ls→
  = QED
  where
  open ∣LocalStep∣ p p′ s mm ls′

  QED : b .epoch  s′ .e-now
  QED with  ls→
  QED |  ProposeBlock {ch = ch} {txs = txs} ph≡′ refl _ _
    with p  p′
  ... | yes refl rewrite lookup✓
    = ⊥-elim (case ph≡ of λ ())
  ... | no p≢ rewrite lookup✖ p≢
    = IH p∈′ ph≡
    where
    p∈′ : p  voteIds (s .history) b
    p∈′ = voteIds-∷˘ {ms = s .history} (Eq.≢-sym p≢) p∈
  QED |  VoteBlock {H = H} {txs = txs} M∈ _ _ _ _ _
    with p  p′
  ... | yes refl rewrite lookup✓
    = ⊥-elim (case ph≡ of λ ())
  ... | no p≢ rewrite lookup✖ p≢
    = IH p∈′ ph≡
    where
    p∈′ : p  voteIds (s .history) b
    p∈′ = voteIds-∷˘ {ms = s .history} (Eq.≢-sym p≢) p∈
  QED |  RegisterVote m∈ _
    = IH p∈ ph≡′
    where
    @ph≡ : (s′  p) .phase  (s  p) .phase
    @ph≡ with p  p′
    ... | no p≢ rewrite lookup✖ p≢ = refl
    ... | yes refl rewrite lookup✓ = refl

    ph≡′ : (s  p) .phase  Ready
    ph≡′ = subst (_≡ _) @ph≡ ph≡
  QED |  FinalizeBlock ch _ _ _
      = IH p∈ ph≡′
      where
      @ph≡ : (s′  p) .phase  (s  p) .phase
      @ph≡ with p  p′
      ... | no p≢ rewrite lookup✖ p≢ = refl
      ... | yes refl rewrite lookup✓ = refl

      ph≡′ : (s  p) .phase  Ready
      ph≡′ = subst (_≡ _) @ph≡ ph≡
... | DishonestLocalStep {p = p′}{m} ¬hp′ h⇒m∈
  = QED
  where
  QED : b .epoch  s′ .e-now
  QED with m ∙block  b
  ... | no b≢
    = IH (voteIds-∷˘′ b≢ p∈) ph≡
  ... | yes refl
    with m ∙pid  p
  ... | no p≢
    = IH (voteIds-∷˘ {ms = s .history} p≢ p∈) ph≡
  ... | yes refl
    = IH (voteIds-accept∈ (h⇒m∈ it) refl refl) ph≡

NoFutureVotes< : StateProperty
NoFutureVotes< s =  {p b}  _ : Honest p  
   p  voteIds (s .history) b
   (s  p) .phase  Ready
    ──────────────────────────
    b .epoch < s .e-now

noFutureVotes< : Invariant NoFutureVotes<
noFutureVotes< Rs p∈ ph≡ =
  Nat.≤∧≢⇒< (noFutureVotes≤ Rs p∈) (noFutureVotes≢ Rs p∈ ph≡)

NoFutureOwnVotes : StateProperty
NoFutureOwnVotes s =  {p m}  _ : Honest p  
   (m ∙block) .epoch  s .e-now
   (s  p) .phase  Ready
   p  m ∙pid
    ──────────────────────────────
    m  (s  p) .db

noFutureOwnVotes : Invariant NoFutureOwnVotes
noFutureOwnVotes (_ , refl , (_ )) {p} bₑ≡e-now ready refl
  rewrite let open ∣Base∣ p in lookup✓
  = L.Any.¬Any[]
noFutureOwnVotes Rs@(_ , refl , (s  _ ⟩←— _))
  {p} {m} bₑ≡enow ready refl m∈db
  = Nat.<⇒≢ bₑ<enow bₑ≡enow
  where
    B = m ∙block

    m∈ : m  s .history
    m∈ = historyComplete Rs m∈db

    p∈ : p  voteIds (s .history) B
    p∈ = voteIds-accept∈ m∈ refl refl

    bₑ<enow : B .epoch < s .e-now
    bₑ<enow =  noFutureVotes< Rs {p} {B} p∈ ready