allQCs
function and its propertiesThe function allQCs extracts allQCs in a list of messages.
-- Decide if it is possible to construct a FormedQC in ms with the data d. Dec-∃FormedQC : ∀ d ms → Dec (∃ λ qc → (qc .payload ≡ d) × FormedQC qc ms) Dec-∃FormedQC d ms with ¿ UniqueMajority⊆ˢ $ map node (voteShares d ms) ¿ ... | no ¬ums = no λ where (qc , refl , all∈) → ¬ums $ qc .shares , voteShares-maximal qc ms all∈ , getUnique qc , getQuorum qc ... | yes (ps , ps⊆ , uniq , maj) = yes (myqc , refl , vss∈) where myqc : QC myqc = record { payload = d ; shares = ps ; uniqueShares = uniq ; quorum = maj } all∈ : All (_∈ map node (voteShares d ms)) ps all∈ = tabulate ps⊆ voteShares⊆ˢms : map Vote (voteShares d ms) ⊆ˢ ms voteShares⊆ˢms = lookup {P = _∈ _} $ map⁺ (voteShares-sound d ms) _vss = map (d signed-by_) ps shares⊆ˢvoteShares : map Vote _vss ⊆ˢ map Vote (voteShares d ms) shares⊆ˢvoteShares = L.SubS.map⁺ Vote $ subst (map (d signed-by_) ps ⊆ˢ_) (sym $ voteShares-lemma d ms) (L.SubS.map⁺ (d signed-by_) ps⊆) vss⊆ˢ : map Vote _vss ⊆ˢ ms vss⊆ˢ = L.SubS.⊆-trans shares⊆ˢvoteShares voteShares⊆ˢms vss∈ : All (_∙∈ ms) _vss vss∈ = map⁻ (tabulate vss⊆ˢ) -- Decide if it is possible to construct a FormedQC with the given VoteShare and -- list of messages, where the VoteShare is considered as an additional Vote. tryQC : ∀ vs ms → ───────────────────────────────────────────────────────────────────── Dec $ ∃ λ qc → (qc .payload ≡ vs .datum) × FormedQC qc (Vote vs ∷ ms) tryQC vs ms = Dec-∃FormedQC (vs .datum) (Vote vs ∷ ms) record AllQCsOf (ms : Messages) (qcs : QCs) : Type where field genesis∈ : qc₀ ∈ qcs sound : qc ∈ qcs → qc ∙∈ ms complete : qc ∙∈ ms → qc .payload ∈ map payload qcs open AllQCsOf open L.All using () renaming (map to amap; zipWith to azipWith) open L.Any using (tail; ++⁺ˡ) open L.Mem using (∈-map⁺; ∈-++⁺ˡ; ∈-++⁺ʳ; ∈-++⁻) allQCs⁺ : (ms : Messages) → ∃ (AllQCsOf ms) allQCs⁺ [] = let qc₀∈ = here refl in [ qc₀ ] , record { genesis∈ = qc₀∈ ; sound = λ where (here refl) → initialQC refl ; complete = λ where (initialQC refl) → ∈-map⁺ payload {x = qc₀} qc₀∈ {qc} (formedQC p) → ⊥-elim $ ¬FormedQC-[] qc p } allQCs⁺ (m ∷ ms) with qs , r ← allQCs⁺ ms with m ... | Propose (b signed-by p) = _qcs , record { genesis∈ = qc₀∈ ; sound = isSound ; complete = λ where (initialQC refl) → ∈-map⁺ payload qc₀∈ {qc} (formedQC p) → there $′ case ¿ qc ∈ tcqs ¿ of λ where (yes qc∈tc) → ∈-map⁺ payload (++⁺ˡ qc∈tc) (no _) → subst (_ ∈_) (sym $ L.map-++ payload _ qs) $ ∈-++⁺ʳ _ $ r .complete $ formedQC {qc} $ amap (tail λ ()) p (receivedQC (here (qc∈-Propose refl))) → here refl (receivedQC (here (qc∈-ProposeTC refl qc∈))) → there $′ ∈-map⁺ payload (++⁺ˡ qc∈) (receivedQC (there p)) → there $′ subst (_ ∈_) (sym (L.map-++ payload _ qs)) $ ∈-++⁺ʳ _ $ r .complete (receivedQC p) } where tcqs = M.fromMaybe [] (M.map qcs (b ∙tc?)) _qcs = b .blockQC ∷ tcqs ++ qs tcqs≡[] : b ∙tc? ≡ nothing → tcqs ≡ [] tcqs≡[] refl = refl tcqs≡ : b ∙tc? ≡ just tc → tcqs ≡ qcs tc tcqs≡ refl = refl qc₀∈ : qc₀ ∈ _qcs qc₀∈ = there $′ ∈-++⁺ʳ tcqs $ r .genesis∈ isSound : qc ∈ _qcs → qc ∙∈ (Propose (b signed-by p) ∷ ms) isSound (here eq) = receivedQC $ here $′ qc∈-Propose eq isSound {qc} (there qc∈) with ∈-++⁻ tcqs qc∈ ... | inj₂ qc∈ʳ = qc∈-monotonic (r .sound qc∈ʳ) ... | inj₁ qc∈ˡ = receivedQC (here QED) where QED : qc qc∈-Message Propose (b signed-by p) QED with b ∙tc? in tc≡ ... | nothing = contradict qc∈ˡ ... | just tc = qc∈-ProposeTC tc≡ qc∈ˡ ... | TCFormed tc = let qc₀∈ = ∈-++⁺ʳ (qcs tc) (r .genesis∈) in qcs tc ++ qs , record { genesis∈ = qc₀∈ ; sound = λ qc∈ → case ∈-++⁻ (qcs tc) qc∈ of λ where (inj₁ qc∈) → receivedQC $ here $′ qc∈-TCFormed qc∈ (inj₂ qc∈) → qc∈-monotonic (r .sound qc∈) ; complete = λ where (initialQC refl) → ∈-map⁺ payload qc₀∈ {qc} (formedQC p) → case ¿ qc ∈₁ (qcs⁺ tc) ¿ of λ where (yes qc∈tc) → ∈-map⁺ payload (++⁺ˡ qc∈tc) (no _) → there $′ subst (_ ∈_) (sym $ L.map-++ payload _ qs) $ ∈-++⁺ʳ _ $ r .complete $ formedQC {qc} $ amap (tail λ ()) p (receivedQC (here (qc∈-TCFormed p))) → ∈-map⁺ payload (∈-++⁺ˡ p) (receivedQC (there p)) → there $′ subst (_ ∈_) (sym (L.map-++ payload _ qs)) $ ∈-++⁺ʳ _ $ r .complete (receivedQC p) } ... | Timeout (te , mtc) = _qcs , record { genesis∈ = qc₀∈ ; sound = isSound ; complete = λ where (initialQC refl) → ∈-map⁺ payload qc₀∈ {qc} (formedQC p) → there $′ case ¿ qc ∈ tcqs ¿ of λ where (yes qc∈tc) → ∈-map⁺ payload (++⁺ˡ qc∈tc) (no _) → subst (_ ∈_) (sym $ L.map-++ payload _ qs) $ ∈-++⁺ʳ _ $ r .complete $ formedQC {qc} (amap (tail λ ()) p) (receivedQC p) → case p of λ where (here (qc∈-Timeout refl)) → here refl (here (qc∈-TimeoutTC refl qc∈)) → there $′ ∈-map⁺ payload (++⁺ˡ qc∈) (there p) → there $′ subst (_ ∈_) (sym (L.map-++ payload _ qs)) $ ∈-++⁺ʳ _ $ r .complete (receivedQC p) } where tcqs = M.fromMaybe [] (M.map qcs mtc) _qcs = te ∙qcTE ∷ tcqs ++ qs tcqs≡[] : mtc ≡ nothing → tcqs ≡ [] tcqs≡[] refl = refl tcqs≡ : mtc ≡ just tc → tcqs ≡ qcs tc tcqs≡ refl = refl qc₀∈ : qc₀ ∈ _qcs qc₀∈ = there $′ ∈-++⁺ʳ tcqs $ r .genesis∈ isSound : qc ∈ _qcs → qc ∙∈ (Timeout (te , mtc) ∷ ms) isSound (here eq) = receivedQC $ here $′ qc∈-Timeout eq isSound {qc} (there qc∈) with ∈-++⁻ tcqs qc∈ ... | inj₂ qc∈ʳ = qc∈-monotonic (r .sound qc∈ʳ) ... | inj₁ qc∈ˡ = receivedQC (here QED) where QED : qc qc∈-Message Timeout (te , mtc) QED with ⟫ mtc ... | ⟫ nothing = contradict qc∈ˡ ... | ⟫ just tc = qc∈-TimeoutTC refl qc∈ˡ ... | Vote v with tryQC v ms ... | no ¬qc = let qc₀∈ = r .genesis∈ in qs , record { genesis∈ = qc₀∈ ; sound = qc∈-monotonic ∘ r .sound ; complete = λ where (initialQC refl) → ∈-map⁺ payload qc₀∈ {qc} (formedQC p) → case qc .payload ≟ v .datum of λ where (yes eq) → ⊥-elim $ ¬qc (qc , eq , p) (no ¬eq) → r .complete $ formedQC {qc} $ azipWith (λ where (v∈ , refl) → tail (λ where refl → ¬eq refl) v∈) (p , qcVoteShares-All qc) (receivedQC (there p)) → r .complete (receivedQC p) } ... | yes (qc , refl , vs) = let qc₀∈ = there $ r .genesis∈ in qc ∷ qs , record { genesis∈ = qc₀∈ ; sound = λ where (here refl) → formedQC vs (there qc∈) → qc∈-monotonic $ r .sound qc∈ ; complete = λ where (initialQC refl) → ∈-map⁺ payload qc₀∈ {qc} (formedQC p) → case qc .payload ≟ v .datum of λ where (yes eq) → here eq (no ¬eq) → there $ r .complete $ formedQC {qc} $ azipWith (λ where (v∈ , refl) → tail (λ where refl → ¬eq refl) v∈) (p , qcVoteShares-All qc) (receivedQC (there p)) → there $ r .complete (receivedQC p) } module _ (ms : Messages) (let qs , r = allQCs⁺ ms) where allQCs : QCs allQCs = qs open AllQCsOf r public renaming ( sound to allQCs-sound ; complete to allQCs-complete ) instance Dec-AllQC : ∀ {r} → AllQC (λ qc → qc ∙round < r) ⁇¹ Dec-AllQC {r = r} {x = ms} .dec = mapDec All⇒AllQC AllQC⇒All dec where P = λ qc → qc ∙round < r All⇒AllQC : All P (allQCs ms) → AllQC P ms All⇒AllQC allP = mk (lookup (L.All.map⁺ allP) ∘′ allQCs-complete ms) AllQC⇒All : AllQC P ms → All P (allQCs ms) AllQC⇒All (mk allP) = L.All.tabulate (allP ∘ allQCs-sound _) highestQC∈ : (ms : Messages) → QC highestQC∈ ms = case allQCs ms of λ where [] → qc₀ (q ∷ qs) → maxNE (q ∷ qs) highestQC∈-is∈ : ∀ ms → ─────────────────── highestQC∈ ms ∙∈ ms highestQC∈-is∈ ms with allQCs ms in eq ... | [] = initialQC refl ... | q ∷ qs = allQCs-sound ms (subst (_ ∈_) (sym eq) (highestQC∈List q qs)) highestQC∈-isHighest : ∀ ms qc′ → qc′ ∙∈ ms ─────────────────────── qc′ ≤qc (highestQC∈ ms) highestQC∈-isHighest ms qc′ qc′∈ with allQCs-complete ms qc′∈ | allQCs ms in eq ... | qcp∈ | q ∷ qs = maxNE-correct {qc′}{q ∷ qs} $ subst (_ ∈_) (cong (map _) eq) qcp∈ ... | qcp∈ | [] = case subst (λ ◆ → _ ∈ map _ ◆) eq qcp∈ of λ () highestQC∈-mono : ∀ m ms → ───────────────────────────────────── highestQC∈ ms ≤qc highestQC∈ (m ∷ ms) highestQC∈-mono m ms = highestQC∈-isHighest (m ∷ ms) (highestQC∈ ms) $ qc∈-monotonic (highestQC∈-is∈ ms)
instance Dec-highest-qc-∈ : _-highest-qc-∈-_ ⁇² Dec-highest-qc-∈ {qc} {ms} .dec with dec ... | no ¬qc∈ = no λ where (isHighest qch∈ _) → ¬qc∈ qch∈ ... | yes qc∈ with qc <qc? highestQC∈ ms ... | yes qc< = no λ where (isHighest _ qch) → Nat.<⇒≱ qc< (qch (highestQC∈ ms) (highestQC∈-is∈ ms)) ... | no ¬qc< = yes $ isHighest qc∈ λ qc′ qc′∈ → Nat.≤-trans (highestQC∈-isHighest ms qc′ qc′∈) (Nat.≮⇒≥ ¬qc<)