{-# OPTIONS --safe --cubical-compatible --exact-split --guardedness --double-check #-}
module ALMA.Prototype.Universe where
open import ALMA.Prototype.Beings public
record IsIndestructible {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃}
(essence : C) (stream : Stream ((I → A) × C)) : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) where
field
essencePermanent : Always (λ x → proj₂ x ≡ essence) stream
open IsIndestructible public
record Universe {ℓ₁ ℓ₂ ℓ₃} (I : Set ℓ₁) (A : Set ℓ₂) (C : Set ℓ₃) : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) where
constructor mkUniverse
field
essence : C
stream : Stream ((I → A) × C)
indestruct : IsIndestructible essence stream
open Universe public
infix 4 _≈ᵁ_
record _≈ᵁ_ {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃}
(u v : Universe I A C) : Set (ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃) where
field
essence≈ : essence u ≡ essence v
stream≈ : stream u ≈ stream v
open _≈ᵁ_ public
≈ᵁ-refl : ∀ {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃} {u : Universe I A C} → u ≈ᵁ u
≈ᵁ-refl = record { essence≈ = refl ; stream≈ = ≈-refl }
≈ᵁ-sym : ∀ {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃} {u v : Universe I A C} → u ≈ᵁ v → v ≈ᵁ u
≈ᵁ-sym eq = record { essence≈ = sym (essence≈ eq) ; stream≈ = ≈-sym (stream≈ eq) }
≈ᵁ-trans : ∀ {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃} {u v w : Universe I A C}
→ u ≈ᵁ v → v ≈ᵁ w → u ≈ᵁ w
≈ᵁ-trans eq1 eq2 = record
{ essence≈ = trans (essence≈ eq1) (essence≈ eq2)
; stream≈ = ≈-trans (stream≈ eq1) (stream≈ eq2)
}
module _ {ℓ₁ ℓ₂ ℓ₃} {I : Set ℓ₁} {A : Set ℓ₂} {C : Set ℓ₃} where
observeAccident : Universe I A C → ℕ → I → A
observeAccident u n i = proj₁ (Stream.head (stream-tail-n (stream u) n)) i
univ-core : Universe I A C → C
univ-core = essence
cosmicStep : Universe I A C → Universe I A C
cosmicStep u = record
{ essence = essence u
; stream = Stream.tail (stream u)
; indestruct = record { essencePermanent = Always.tail (essencePermanent (indestruct u)) }
}
cosmicStep-preserves-core : ∀ u → univ-core (cosmicStep u) ≡ univ-core u
cosmicStep-preserves-core u = refl
univ-essence-constant : ∀ u n → proj₂ (Stream.head (stream-tail-n (stream u) n)) ≡ univ-core u
univ-essence-constant u n = always-implies-all-n (essencePermanent (indestruct u)) n
univ-deterministic-observation : ∀ u n i → Σ A (λ a → observeAccident u n i ≡ a)
univ-deterministic-observation u n i = observeAccident u n i , refl
Selector : ℕ → Set
Selector n = Fin n → ℕ
proj-stream : ∀ {ℓ₁ ℓ₂} (A : Set ℓ₁) (C : Set ℓ₂) n
→ Stream ((ℕ → A) × C) → Selector n → Stream ((Fin n → A) × C)
proj-stream A C n s sel .Stream.head = (λ i → proj₁ (Stream.head s) (sel i)) , proj₂ (Stream.head s)
proj-stream A C n s sel .Stream.tail = proj-stream A C n (Stream.tail s) sel
private
core-const : ∀ {ℓ₁ ℓ₂} (A : Set ℓ₁) (C : Set ℓ₂) n s sel (c : C)
→ Always (λ x → proj₂ x ≡ c) s
→ Always (λ x → proj₂ x ≡ c) (proj-stream A C n s sel)
core-const A C n s sel c al .Always.head = al .Always.head
core-const A C n s sel c al .Always.tail = core-const A C n (Stream.tail s) sel c (al .Always.tail)
projGeneric : ∀ {ℓ} n {C : Set ℓ} → Selector n → Universe ℕ ℕ C → Universe (Fin n) ℕ C
projGeneric n {C} sel cos = record
{ essence = univ-core cos
; stream = proj-stream ℕ C n (stream cos) sel
; indestruct = record
{ essencePermanent = core-const ℕ C n (stream cos) sel (univ-core cos)
(essencePermanent (indestruct cos)) }
}
proj-preserves-core : ∀ {ℓ} n {C : Set ℓ} sel (cos : Universe ℕ ℕ C) →
essence (projGeneric n sel cos) ≡ univ-core cos
proj-preserves-core n sel cos = refl
module MergeSelectors (n m : ℕ) where
merge : (Fin n → ℕ) → (Fin m → ℕ) → Fin (n + m) → ℕ
merge sel₁ sel₂ i = [_,_] sel₁ sel₂ (splitAt n i)
merge-preserves-core : ∀ {ℓ} {C : Set ℓ} (cos : Universe ℕ ℕ C) (sel₁ : Fin n → ℕ) (sel₂ : Fin m → ℕ) →
essence (projGeneric (n + m) (merge sel₁ sel₂) cos) ≡ univ-core cos
merge-preserves-core cos sel₁ sel₂ = refl
data Cosmos-C : Set where
CosmicEssence : Cosmos-C
open Cosmos-C public
StreamCosmos : Set
StreamCosmos = Universe ℕ ℕ Cosmos-C
proj-stream-cosmos : ∀ n → Stream ((ℕ → ℕ) × Cosmos-C) → Selector n → Stream ((Fin n → ℕ) × Cosmos-C)
proj-stream-cosmos = proj-stream ℕ Cosmos-C
private
core-const-cosmos : ∀ n s sel (c : Cosmos-C) → Always (λ x → proj₂ x ≡ c) s →
Always (λ x → proj₂ x ≡ c) (proj-stream-cosmos n s sel)
core-const-cosmos = core-const ℕ Cosmos-C
projCosmos : ∀ n → Selector n → StreamCosmos → Universe (Fin n) ℕ Cosmos-C
projCosmos n sel cos = record
{ essence = univ-core cos
; stream = proj-stream-cosmos n (stream cos) sel
; indestruct = record
{ essencePermanent = core-const-cosmos n (stream cos) sel (univ-core cos)
(essencePermanent (indestruct cos)) }
}
cos-observe : StreamCosmos → ℕ → ℕ → ℕ
cos-observe = observeAccident {I = ℕ} {A = ℕ} {C = Cosmos-C}
infix 4 _≈ᶜ_
record _≈ᶜ_ (x y : StreamCosmos) : Set where
field
essence≈ : essence x ≡ essence y
stream≈ : stream x ≈ stream y
open _≈ᶜ_ public
≈ᶜ-refl : ∀ {x} → x ≈ᶜ x
≈ᶜ-refl = record { essence≈ = refl ; stream≈ = ≈-refl }
≈ᶜ-sym : ∀ {x y} → x ≈ᶜ y → y ≈ᶜ x
≈ᶜ-sym eq = record { essence≈ = sym (essence≈ eq) ; stream≈ = ≈-sym (stream≈ eq) }
≈ᶜ-trans : ∀ {x y z} → x ≈ᶜ y → y ≈ᶜ z → x ≈ᶜ z
≈ᶜ-trans eq1 eq2 = record
{ essence≈ = trans (essence≈ eq1) (essence≈ eq2)
; stream≈ = ≈-trans (stream≈ eq1) (stream≈ eq2)
}
cosmos-essence-unique : ∀ (cos1 cos2 : StreamCosmos) → essence cos1 ≡ essence cos2
cosmos-essence-unique cos1 cos2 with essence cos1 | essence cos2
... | CosmicEssence | CosmicEssence = refl
cosmos-initial : (ℕ → ℕ) → StreamCosmos
cosmos-initial o = record
{ essence = CosmicEssence
; stream = constStream (o , CosmicEssence)
; indestruct = record { essencePermanent = constStream-always-gen (o , CosmicEssence) refl }
}
private
extend-fun : ∀ {n} → (Fin n → ℕ) → (ℕ → ℕ)
extend-fun f i = maybe f 0 (toFin i)
embedToCosmos : ∀ {n} → Stream ((Fin n → ℕ) × Cosmos-C) → Stream ((ℕ → ℕ) × Cosmos-C)
embedToCosmos s .Stream.head = (extend-fun (proj₁ (Stream.head s))) , proj₂ (Stream.head s)
embedToCosmos s .Stream.tail = embedToCosmos (Stream.tail s)
extend-always : ∀ {n} {s : Stream ((Fin n → ℕ) × Cosmos-C)} {c : Cosmos-C}
→ Always (λ x → proj₂ x ≡ c) s
→ Always (λ x → proj₂ x ≡ c) (embedToCosmos s)
extend-always alw .Always.head = alw .Always.head
extend-always alw .Always.tail = extend-always (alw .Always.tail)
private
infix 4 _≈obs_
record _≈obs_ {n} (s t : Stream ((Fin n → ℕ) × Cosmos-C)) : Set where
coinductive
field
head-obs-equiv : ∀ (i : Fin n) →
proj₁ (Stream.head s) i ≡ proj₁ (Stream.head t) i
head-essence-equiv : proj₂ (Stream.head s) ≡ proj₂ (Stream.head t)
tail-equiv : Stream.tail s ≈obs Stream.tail t
open _≈obs_
≈obs-refl : ∀ {n} {s : Stream ((Fin n → ℕ) × Cosmos-C)} → s ≈obs s
≈obs-refl .head-obs-equiv i = refl
≈obs-refl .head-essence-equiv = refl
≈obs-refl .tail-equiv = ≈obs-refl
≈obs-sym : ∀ {n} {s t : Stream ((Fin n → ℕ) × Cosmos-C)} → s ≈obs t → t ≈obs s
≈obs-sym eq .head-obs-equiv i = sym (eq .head-obs-equiv i)
≈obs-sym eq .head-essence-equiv = sym (eq .head-essence-equiv)
≈obs-sym eq .tail-equiv = ≈obs-sym (eq .tail-equiv)
trans-≈obs : ∀ {n} {s t u : Stream ((Fin n → ℕ) × Cosmos-C)} → s ≈obs t → t ≈obs u → s ≈obs u
trans-≈obs eq1 eq2 .head-obs-equiv i = trans (eq1 .head-obs-equiv i) (eq2 .head-obs-equiv i)
trans-≈obs eq1 eq2 .head-essence-equiv = trans (eq1 .head-essence-equiv) (eq2 .head-essence-equiv)
trans-≈obs eq1 eq2 .tail-equiv = trans-≈obs (eq1 .tail-equiv) (eq2 .tail-equiv)
proj-extend-obs-equiv : ∀ {n} (s : Stream ((Fin n → ℕ) × Cosmos-C))
→ proj-stream-cosmos n (embedToCosmos s) (λ i → toℕ i) ≈obs s
proj-extend-obs-equiv {n} s = helper
where
helper : proj-stream-cosmos n (embedToCosmos s) (λ i → toℕ i) ≈obs s
helper .head-obs-equiv i =
trans refl
(trans refl
(trans (cong (maybe (proj₁ (Stream.head s)) 0) (toFin-toℕ i))
refl))
helper .head-essence-equiv = refl
helper .tail-equiv = proj-extend-obs-equiv (Stream.tail s)
open _≈obs_ public
universe-to-cosmos : ∀ {n} → Universe (Fin n) ℕ Cosmos-C → StreamCosmos
universe-to-cosmos u = record
{ essence = essence u
; stream = embedToCosmos (stream u)
; indestruct = record { essencePermanent = extend-always (essencePermanent (indestruct u)) }
}
embedToCosmos-preserves-≈ : ∀ {n_len} {s t : Stream ((Fin n_len → ℕ) × Cosmos-C)}
→ s ≈ t → embedToCosmos s ≈ embedToCosmos t
embedToCosmos-preserves-≈ eq ._≈_.head≈ =
cong₂ _,_ (cong extend-fun (cong proj₁ (eq ._≈_.head≈))) (cong proj₂ (eq ._≈_.head≈))
embedToCosmos-preserves-≈ eq ._≈_.tail≈ = embedToCosmos-preserves-≈ (eq ._≈_.tail≈)
proj-≈ᵁ : ∀ {n} (sel : Fin n → ℕ) {cos1 cos2 : StreamCosmos} → cos1 ≈ᶜ cos2 → projCosmos n sel cos1 ≈ᵁ projCosmos n sel cos2
proj-≈ᵁ {n} sel {cos1} {cos2} eq = record
{ essence≈ = trans (proj-preserves-core n sel cos1)
(trans (essence≈ eq)
(sym (proj-preserves-core n sel cos2)))
; stream≈ = proj-stream-≈ (stream≈ eq)
}
where
proj-stream-≈ : {s1 s2 : Stream ((ℕ → ℕ) × Cosmos-C)} → s1 ≈ s2 →
proj-stream-cosmos n s1 sel ≈ proj-stream-cosmos n s2 sel
proj-stream-≈ eq ._≈_.head≈ = cong (λ x → (λ i → proj₁ x (sel i)) , proj₂ x) (_≈_.head≈ eq)
proj-stream-≈ eq ._≈_.tail≈ = proj-stream-≈ (_≈_.tail≈ eq)
≈ᵁ-implies-≈obs : ∀ {n} {u1 u2 : Universe (Fin n) ℕ Cosmos-C} → u1 ≈ᵁ u2 → stream u1 ≈obs stream u2
≈ᵁ-implies-≈obs {n} eq = helper {n} (eq .stream≈)
where
helper : ∀ {n} {s t : Stream ((Fin n → ℕ) × Cosmos-C)} → s ≈ t → s ≈obs t
helper eq .head-obs-equiv i = cong (λ f → f i) (cong proj₁ (eq ._≈_.head≈))
helper eq .head-essence-equiv = cong proj₂ (eq ._≈_.head≈)
helper eq .tail-equiv = helper (eq ._≈_.tail≈)
proj-embed-unit : ∀ {n} (u : Universe (Fin n) ℕ Cosmos-C) →
stream (projCosmos n (λ i → toℕ i) (universe-to-cosmos u)) ≈obs stream u
proj-embed-unit u = proj-extend-obs-equiv (stream u)
universe-embedding-uniqueness :
∀ {n} (u1 u2 : Universe (Fin n) ℕ Cosmos-C)
→ stream u1 ≈obs stream u2
→ Σ StreamCosmos (λ cos →
(Σ (Fin n → ℕ) (λ sel1 → stream (projCosmos n sel1 cos) ≈obs stream u1))
×
(Σ (Fin n → ℕ) (λ sel2 → stream (projCosmos n sel2 cos) ≈obs stream u2))
)
universe-embedding-uniqueness {n} u1 u2 stream-obs =
(cos , ((sel1 , bisim1) , (sel2 , bisim2)))
where
cos : StreamCosmos
cos = universe-to-cosmos u1
sel1 : Fin n → ℕ
sel1 i = toℕ i
sel2 : Fin n → ℕ
sel2 i = toℕ i
bisim1 : stream (projCosmos n sel1 cos) ≈obs stream u1
bisim1 = proj-extend-obs-equiv (stream u1)
bisim2 : stream (projCosmos n sel2 cos) ≈obs stream u2
bisim2 = trans-≈obs (proj-extend-obs-equiv (stream u1)) stream-obs
infix 4 _≈∞_
record _≈∞_ (s t : Stream ((ℕ → ℕ) × Cosmos-C)) : Set where
coinductive
field
head-pointwise : ∀ (k : ℕ) → proj₁ (Stream.head s) k ≡ proj₁ (Stream.head t) k
head-essence : proj₂ (Stream.head s) ≡ proj₂ (Stream.head t)
tail-pointwise : Stream.tail s ≈∞ Stream.tail t
open _≈∞_ public
triangle1-pointwise : ∀ {n_len} (u : Universe (Fin n_len) ℕ Cosmos-C)
→ stream (universe-to-cosmos (projCosmos n_len (λ i → toℕ i) (universe-to-cosmos u)))
≈∞ stream (universe-to-cosmos u)
triangle1-pointwise {n_len} u = helper
where
f : Fin n_len → ℕ
f = proj₁ (Stream.head (stream u))
general-lemma : ∀ (m : Maybe (Fin n_len))
→ maybe (λ i → maybe f 0 (toFin (toℕ i))) 0 m
≡ maybe f 0 m
general-lemma nothing = refl
general-lemma (just i) = cong (λ x → maybe f 0 x) (toFin-toℕ i)
helper : stream (universe-to-cosmos (projCosmos n_len (λ i → toℕ i) (universe-to-cosmos u)))
≈∞ stream (universe-to-cosmos u)
helper .head-pointwise k = general-lemma (toFin k)
helper .head-essence = refl
helper .tail-pointwise = triangle1-pointwise (cosmicStep u)
module GeneralNoReconstruction (n : ℕ) where
obs-selector : Fin n → ℕ
obs-selector i = toℕ i
cosmic-view-1 cosmic-view-2 : ℕ → ℕ
cosmic-view-1 _ = 0
cosmic-view-2 k = if k <ᵇ n then 0 else 1
cosmos-instance-1 : StreamCosmos
cosmos-instance-1 = cosmos-initial cosmic-view-1
cosmos-instance-2 : StreamCosmos
cosmos-instance-2 = cosmos-initial cosmic-view-2
finite-obs-equiv : stream (projCosmos n obs-selector cosmos-instance-1) ≈obs
stream (projCosmos n obs-selector cosmos-instance-2)
finite-obs-equiv .head-obs-equiv i =
sym (cong (λ b → if b then 0 else 1) (<⇒<ᵇ-eq (toℕ<n i)))
finite-obs-equiv .head-essence-equiv = refl
finite-obs-equiv .tail-equiv = finite-obs-equiv
¬cosmos1≈cosmos2 : ¬ (cosmos-instance-1 ≈ᶜ cosmos-instance-2)
¬cosmos1≈cosmos2 eq = 0≢1 (trans (f-eq n) view2-n-eq1)
where
head≡ : Stream.head (stream cosmos-instance-1) ≡ Stream.head (stream cosmos-instance-2)
head≡ = stream≈ eq ._≈_.head≈
view≡ : cosmic-view-1 ≡ cosmic-view-2
view≡ = cong proj₁ head≡
f-eq : ∀ (x : ℕ) → cosmic-view-1 x ≡ cosmic-view-2 x
f-eq x = cong (λ f → f x) view≡
view2-n-eq1 : cosmic-view-2 n ≡ 1
view2-n-eq1 rewrite <ᵇ-self-false n = refl
0≢1 : 0 ≢ 1
0≢1 ()
general-no-reconstruction :
¬ ( Σ[ recover ∈ (Universe (Fin n) ℕ Cosmos-C → StreamCosmos) ]
( (∀ u v → stream u ≈obs stream v → recover u ≈ᶜ recover v) ×
(∀ cos → recover (projCosmos n obs-selector cos) ≈ᶜ cos) ) )
general-no-reconstruction (f , pres , prop) =
¬cosmos1≈cosmos2 (≈ᶜ-trans (≈ᶜ-sym (prop cosmos-instance-1))
(≈ᶜ-trans (pres _ _ finite-obs-equiv)
(prop cosmos-instance-2)))
module CosmosLevel where
WeakHom-Cosmos : StreamCosmos → Set
WeakHom-Cosmos cos = ∀ n m i → cos-observe cos n i ≡ cos-observe cos m i
Changes-Cosmos : StreamCosmos → Set
Changes-Cosmos cos = ∃ λ n → ∃ λ i → cos-observe cos n i ≢ cos-observe cos (suc n) i
Generator : (O C : Set) → Set₁
Generator O C = Σ Set (λ S → S × (S → (O × C) × S))
genStream : ∀ {O C} → Generator O C → Stream (O × C)
genStream (S , init , step) = ana step init
WeakHomG : ∀ {O C} → Generator O C → Set
WeakHomG g = WeakHomS (genStream g)
ChangesG : ∀ {O C} → Generator O C → Set
ChangesG g = ChangesS (genStream g)
module _ {O C : Set} where
const-output→WeakHomG : (S : Set) (init : S) (step : S → (O × C) × S)
→ (∀ s → proj₁ (step s) ≡ proj₁ (step init))
→ WeakHomG (S , init , step)
const-output→WeakHomG S init step const-out = weak
where
o₀ = proj₁ (proj₁ (step init))
lemma : (s : S) → ∀ n → proj₁ (head (stream-tail-n (ana step s) n)) ≡ o₀
lemma s zero = cong proj₁ (const-out s)
lemma s (suc n) = lemma (proj₂ (step s)) n
weak : WeakHomS (ana step init)
weak n m = trans (lemma init n) (sym (lemma init m))
WeakHomCoind : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Stream (O × C) → Set (ℓ₁ ⊔ ℓ₂)
WeakHomCoind s = s ≈ constStream (head s)
coind-const→all-heads : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} {s : Stream (O × C)} {a : O × C}
→ s ≈ constStream a
→ ∀ n → head (stream-tail-n s n) ≡ a
coind-const→all-heads eq zero = _≈_.head≈ eq
coind-const→all-heads eq (suc n) = coind-const→all-heads (_≈_.tail≈ eq) n
coind→pointwise : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (s : Stream (O × C)) → WeakHomCoind s
→ ∀ n → head (stream-tail-n s n) ≡ head s
coind→pointwise s coind = coind-const→all-heads coind
LocalChangeCosmos : ℕ → StreamCosmos → Set
LocalChangeCosmos d cos = ∃ λ n → ∃ λ m → cos-observe cos n d ≢ cos-observe cos m d
GlobalChangeCosmos : StreamCosmos → Set
GlobalChangeCosmos cos = ∀ d → LocalChangeCosmos d cos
FrequentChangeCosmos : StreamCosmos → Set
FrequentChangeCosmos cos =
∀ n → ∃ λ m → n ≤ m × (∃ λ d → cos-observe cos m d ≢ cos-observe cos (suc m) d)
PeriodicCosmos : ℕ → StreamCosmos → Set
PeriodicCosmos k cos = ∀ n i → cos-observe cos n i ≡ cos-observe cos (n + k) i
open CosmosLevel
weakHomCosmos→¬localChange : ∀ cos → WeakHom-Cosmos cos → ∀ d → ¬ LocalChangeCosmos d cos
weakHomCosmos→¬localChange cos w d (n , m , neq) = neq (w n m d)
HomS : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Stream (O × C) → Set (ℓ₁ ⊔ ℓ₂)
HomS {O = O} {C = C} s = ∀ (t : Stream (O × C)) n m → obsS s n ≡ obsS t m
homS→weakHomS : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} {s : Stream (O × C)} → HomS s → WeakHomS s
homS→weakHomS {s = s} hom n m = hom s n m
altGen : (C : Set) → C → Generator Bool C
altGen C c = Bool , true , step
where
step : Bool → (Bool × C) × Bool
step b = ((b , c) , not b)
altGen-changes : ∀ {C} (c : C) → ChangesS (genStream (altGen _ c))
altGen-changes c = 0 , λ eq → true≢false eq
no-possible-hom : ∀ {C : Set} (c : C) → ¬ (∃ λ (g : Generator Bool C) → HomS (genStream g))
no-possible-hom {C} c (g , hom) =
let
altStream = genStream (altGen _ c)
(n , neq) = altGen-changes c
eq1 : obsS (genStream g) n ≡ obsS altStream n
eq1 = hom altStream n n
eq2 : obsS (genStream g) n ≡ obsS altStream (suc n)
eq2 = hom altStream n (suc n)
eq : obsS altStream n ≡ obsS altStream (suc n)
eq = trans (sym eq1) eq2
in ⊥-elim (neq eq)
WeakHom : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Process O C → Set ℓ₁
WeakHom p = WeakHomS (stream p)
Changes : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Process O C → Set ℓ₁
Changes p = ChangesS (stream p)
Δ : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Process O C → Set ℓ₁
Δ p = ΔS (stream p)
lemma-WeakHom→¬Changes : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → WeakHom p → ¬ Changes p
lemma-WeakHom→¬Changes p weak (n , neq) = neq (weak n (suc n))
lemma-WeakHom→¬Boundary : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → WeakHom p → ¬ Δ p
lemma-WeakHom→¬Boundary p weak (n , m , neq) = neq (weak n m)
lemma-SelfSubstantial→¬WeakHom : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → Δ p → ¬ WeakHom p
lemma-SelfSubstantial→¬WeakHom p delta weak = lemma-WeakHom→¬Boundary p weak delta
StrongHom : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} → Process O C → Set (ℓ₁ ⊔ ℓ₂)
StrongHom {O = O} {C = C} p = ∀ (q : Process O C) n m → observe p n ≡ observe q m
hom→weakHom : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → StrongHom p → WeakHom p
hom→weakHom p hom-p n m = hom-p p n m
thm-Hom→¬Changes : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → StrongHom p → ¬ Changes p
thm-Hom→¬Changes p hom = lemma-WeakHom→¬Changes p (hom→weakHom p hom)
thm-Hom→¬Boundary : ∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (p : Process O C) → StrongHom p → ¬ Δ p
thm-Hom→¬Boundary p hom = lemma-WeakHom→¬Boundary p (hom→weakHom p hom)
thm-no-Hom-if-any-change :
∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (FB : Process O C) → Changes FB → ¬ (∃ λ (p : Process O C) → StrongHom p)
thm-no-Hom-if-any-change FB (n , neq) (p , hom-p) =
⊥-elim (neq (trans (sym (hom-p FB n n)) (hom-p FB n (suc n))))
nonuniformity-inevitable :
∀ {ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂} (FB : Process O C) → Changes FB → (∀ p → ¬ StrongHom p)
nonuniformity-inevitable FB changes p hom-p =
thm-no-Hom-if-any-change FB changes (p , hom-p)
module WithFact
{ℓ₁ ℓ₂} {O : Set ℓ₁} {C : Set ℓ₂}
(FB : Process O C)
(fact-FB-changes : Changes FB)
where
concrete-nonuniformity : ∀ p → ¬ StrongHom p
concrete-nonuniformity = nonuniformity-inevitable FB fact-FB-changes
lemma-Hom-Cosmos→¬Changes-Cosmos : (cos : StreamCosmos) → WeakHom-Cosmos cos → ¬ Changes-Cosmos cos
lemma-Hom-Cosmos→¬Changes-Cosmos cos hom (n , i , neq) = neq (hom n (suc n) i)
module Ontological where
transform : ∀ {O₁ O₂ C : Set} → ((O₁ × O₂) × (C × C)) → ((O₁ × O₂) × C)
transform ((o12 , (c1 , c2))) = (o12 , c1)
interact : ∀ {O₁ O₂ C : Set}
→ Process O₁ C
→ Process O₂ C
→ Process (O₁ × O₂) C
interact {O₁} {O₂} {C} p1 p2 =
mkProc
(o p1 , o p2)
(core p1)
(map-stream transform (merge-stream (stream p1) (stream p2)))
transformed-essence-const
transformed-init-consistent
where
transformed-essence-const : Always (λ x → proj₂ x ≡ core p1)
(map-stream transform (merge-stream (stream p1) (stream p2)))
transformed-essence-const = helper (stream p1) (stream p2) (essence-const p1)
where
helper : ∀ (s1 : Stream (O₁ × C)) (s2 : Stream (O₂ × C))
→ Always (λ x → proj₂ x ≡ core p1) s1
→ Always (λ x → proj₂ x ≡ core p1) (map-stream transform (merge-stream s1 s2))
helper s1 s2 alw1 .Always.head =
begin
proj₂ (transform (head (merge-stream s1 s2)))
≡⟨ refl ⟩
proj₂ (head s1)
≡⟨ Always.head alw1 ⟩
core p1
∎
helper s1 s2 alw1 .Always.tail =
helper (tail s1) (tail s2) (Always.tail alw1)
transformed-init-consistent : proj₁ (head (map-stream transform (merge-stream (stream p1) (stream p2))))
≡ (o p1 , o p2)
transformed-init-consistent =
begin
proj₁ (transform (head (merge-stream (stream p1) (stream p2))))
≡⟨ refl ⟩
(proj₁ (head (stream p1)) , proj₁ (head (stream p2)))
≡⟨ cong₂ _,_ (init-consistent p1) (init-consistent p2) ⟩
(o p1 , o p2)
∎
core-interact : ∀ {O₁ O₂ C : Set}
(p1 : Process O₁ C)
(p2 : Process O₂ C)
→ core (interact p1 p2) ≡ core p1
core-interact p1 p2 = refl
core-interact-sym : ∀ {O₁ O₂ C : Set}
(p1 : Process O₁ C)
(p2 : Process O₂ C)
→ core p1 ≡ core p2
→ core (interact p1 p2) ≡ core p2
core-interact-sym p1 p2 eq = trans (core-interact p1 p2) eq
observe-interact : ∀ {O₁ O₂ C : Set}
(p1 : Process O₁ C)
(p2 : Process O₂ C)
→ ∀ n → observe (interact p1 p2) n ≡ (observe p1 n , observe p2 n)
observe-interact p1 p2 n =
begin
observe (interact p1 p2) n
≡⟨ refl ⟩
proj₁ (head (stream-tail-n (map-stream transform (merge-stream (stream p1) (stream p2))) n))
≡⟨ cong proj₁ (map-stream-tail-n transform (merge-stream (stream p1) (stream p2)) n) ⟩
proj₁ (transform (head (stream-tail-n (merge-stream (stream p1) (stream p2)) n)))
≡⟨ refl ⟩
proj₁ (head (stream-tail-n (merge-stream (stream p1) (stream p2)) n))
≡⟨ merge-stream-observe (stream p1) (stream p2) n ⟩
(proj₁ (head (stream-tail-n (stream p1) n)), proj₁ (head (stream-tail-n (stream p2) n)))
≡⟨ refl ⟩
(observe p1 n , observe p2 n)
∎
module Epistemic where
open Ontological public
Coupling : {O₁ O₂ C : Set} → Set
Coupling {O₁} {O₂} {C} =
(p1 : Process O₁ C)
(p2 : Process O₂ C)
→ Σ (Process (O₁ × O₂) C)
(λ p' → (core p' ≡ core p1)
× (∀ n → observe p' n ≡ (observe p1 n , observe p2 n)))
canonical-coupling : {O₁ O₂ C : Set} → Coupling {O₁} {O₂} {C}
canonical-coupling p1 p2 =
interact p1 p2 , core-interact p1 p2 , observe-interact p1 p2
interact-with : {O₁ O₂ C : Set}
→ Coupling {O₁} {O₂} {C}
→ Process O₁ C
→ Process O₂ C
→ Process (O₁ × O₂) C
interact-with coupling p1 p2 = proj₁ (coupling p1 p2)
core-interact-epistemic : {O₁ O₂ C : Set}
→ (coupling : Coupling {O₁} {O₂} {C})
→ (p1 : Process O₁ C)
→ (p2 : Process O₂ C)
→ core (interact-with coupling p1 p2) ≡ core p1
core-interact-epistemic coupling p1 p2 = proj₁ (proj₂ (coupling p1 p2))
observe-interact-epistemic : {O₁ O₂ C : Set}
→ (coupling : Coupling {O₁} {O₂} {C})
→ (p1 : Process O₁ C)
→ (p2 : Process O₂ C)
→ ∀ n → observe (interact-with coupling p1 p2) n
≡ (observe p1 n , observe p2 n)
observe-interact-epistemic coupling p1 p2 n = proj₂ (proj₂ (coupling p1 p2)) n
open Ontological public
open Epistemic public
interact-functor₁ : ∀ {O₁ O₂ C} {p₁ p₁' : Process O₁ C} {p₂ : Process O₂ C} →
p₁ ≈ₚ p₁' → interact p₁ p₂ ≈ₚ interact p₁' p₂
interact-functor₁ {p₁ = p₁} {p₁'} {p₂} p₁≈p₁' = helper (stream p₁) (stream p₁') (stream p₂) p₁≈p₁'
where
helper : ∀ {O₁ O₂ C} (s₁ s₁' : Stream (O₁ × C)) (s₂ : Stream (O₂ × C)) →
s₁ ≈ s₁' → map-stream transform (merge-stream s₁ s₂) ≈ map-stream transform (merge-stream s₁' s₂)
helper s₁ s₁' s₂ eq ._≈_.head≈ = cong transform (cong (λ x → merge-state x (Stream.head s₂)) (_≈_.head≈ eq))
helper s₁ s₁' s₂ eq ._≈_.tail≈ = helper (Stream.tail s₁) (Stream.tail s₁') (Stream.tail s₂) (_≈_.tail≈ eq)
interact-functor₂ : ∀ {O₁ O₂ C} {p₁ : Process O₁ C} {p₂ p₂' : Process O₂ C} →
p₂ ≈ₚ p₂' → interact p₁ p₂ ≈ₚ interact p₁ p₂'
interact-functor₂ {p₁ = p₁} {p₂} {p₂'} p₂≈p₂' = helper (stream p₁) (stream p₂) (stream p₂') p₂≈p₂'
where
helper : ∀ {O₁ O₂ C} (s₁ : Stream (O₁ × C)) (s₂ s₂' : Stream (O₂ × C)) →
s₂ ≈ s₂' → map-stream transform (merge-stream s₁ s₂) ≈ map-stream transform (merge-stream s₁ s₂')
helper s₁ s₂ s₂' eq ._≈_.head≈ = cong transform (cong (merge-state (Stream.head s₁)) (_≈_.head≈ eq))
helper s₁ s₂ s₂' eq ._≈_.tail≈ = helper (Stream.tail s₁) (Stream.tail s₂) (Stream.tail s₂') (_≈_.tail≈ eq)
interact-functor : ∀ {O₁ O₂ C} {p₁ p₁' : Process O₁ C} {p₂ p₂' : Process O₂ C} →
p₁ ≈ₚ p₁' → p₂ ≈ₚ p₂' → interact p₁ p₂ ≈ₚ interact p₁' p₂'
interact-functor {O₁} {O₂} {C} {p₁} {p₁'} {p₂} {p₂'} eq1 eq2 =
helper {O₁} {O₂} {C} (stream p₁) (stream p₁') (stream p₂) (stream p₂') eq1 eq2
where
helper : ∀ {O₁ O₂ C} (s₁ s₁' : Stream (O₁ × C)) (s₂ s₂' : Stream (O₂ × C)) →
s₁ ≈ s₁' → s₂ ≈ s₂' →
map-stream transform (merge-stream s₁ s₂) ≈ map-stream transform (merge-stream s₁' s₂')
helper s₁ s₁' s₂ s₂' eq1 eq2 ._≈_.head≈ =
cong transform (cong₂ merge-state (_≈_.head≈ eq1) (_≈_.head≈ eq2))
helper s₁ s₁' s₂ s₂' eq1 eq2 ._≈_.tail≈ =
helper (Stream.tail s₁) (Stream.tail s₁') (Stream.tail s₂) (Stream.tail s₂')
(_≈_.tail≈ eq1) (_≈_.tail≈ eq2)
interact-core-comm : ∀ {O₁ O₂ C} (p₁ : Process O₁ C) (p₂ : Process O₂ C) →
core (interact p₁ p₂) ≡ core p₁
interact-core-comm = core-interact
interact-next-comm : ∀ {O₁ O₂ C} (p₁ : Process O₁ C) (p₂ : Process O₂ C) →
next (interact p₁ p₂) ≈ₚ interact (next p₁) (next p₂)
interact-next-comm p₁ p₂ = helper (stream p₁) (stream p₂)
where
helper : ∀ {O₁ O₂ C} (s₁ : Stream (O₁ × C)) (s₂ : Stream (O₂ × C)) →
Stream.tail (map-stream transform (merge-stream s₁ s₂)) ≈
map-stream transform (merge-stream (Stream.tail s₁) (Stream.tail s₂))
helper s₁ s₂ ._≈_.head≈ = refl
helper s₁ s₂ ._≈_.tail≈ = helper (Stream.tail s₁) (Stream.tail s₂)
interact-observe-comm : ∀ {O₁ O₂ C} (p₁ : Process O₁ C) (p₂ : Process O₂ C) (n : ℕ) →
observe (interact p₁ p₂) n ≡ (observe p₁ n , observe p₂ n)
interact-observe-comm = observe-interact
assoc-interact-O : ∀ {O₁ O₂ O₃ : Set} → ((O₁ × O₂) × O₃) → (O₁ × (O₂ × O₃))
assoc-interact-O ((o₁ , o₂) , o₃) = (o₁ , (o₂ , o₃))
interact-assoc : ∀ {O₁ O₂ O₃ C}
(p₁ : Process O₁ C) (p₂ : Process O₂ C) (p₃ : Process O₃ C) →
≈ₚ-hetero (interact (interact p₁ p₂) p₃)
(interact p₁ (interact p₂ p₃))
assoc-interact-O id
interact-assoc p₁ p₂ p₃ = record { stream≈ = helper (stream p₁) (stream p₂) (stream p₃) }
where
helper : ∀ {O₁ O₂ O₃ C} (s₁ : Stream (O₁ × C)) (s₂ : Stream (O₂ × C)) (s₃ : Stream (O₃ × C)) →
≈-hetero (map-stream transform (merge-stream (map-stream transform (merge-stream s₁ s₂)) s₃))
(map-stream transform (merge-stream s₁ (map-stream transform (merge-stream s₂ s₃))))
(comb assoc-interact-O id)
helper s₁ s₂ s₃ .head≈ = refl
helper s₁ s₂ s₃ .tail≈ = helper (Stream.tail s₁) (Stream.tail s₂) (Stream.tail s₃)
interact-comm : ∀ {O₁ O₂ C} (p₁ : Process O₁ C) (p₂ : Process O₂ C) →
core p₁ ≡ core p₂ →
≈ₚ-hetero (interact p₁ p₂) (interact p₂ p₁) swap-O id
interact-comm {O₁} {O₂} {C} p₁ p₂ eq =
record { stream≈ = helper (stream p₁) (stream p₂) (essence-const p₁) (essence-const p₂) }
where
helper : (s₁ : Stream (O₁ × C)) (s₂ : Stream (O₂ × C)) →
Always (λ x → proj₂ x ≡ core p₁) s₁ →
Always (λ x → proj₂ x ≡ core p₂) s₂ →
≈-hetero (map-stream transform (merge-stream s₁ s₂))
(map-stream transform (merge-stream s₂ s₁))
(comb swap-O id)
helper s₁ s₂ alw₁ alw₂ .head≈ =
let c1≡c2 = trans (alw₁ .Always.head) (trans eq (sym (alw₂ .Always.head)))
in cong₂ _,_ refl c1≡c2
helper s₁ s₂ alw₁ alw₂ .tail≈ =
helper (Stream.tail s₁) (Stream.tail s₂) (Always.tail alw₁) (Always.tail alw₂)
interact-from-⊗ : ∀ {O₁ O₂ C} (p₁ : Process O₁ C) (p₂ : Process O₂ C) →
≈ₚ-hetero (p₁ ⊗ p₂) (interact p₁ p₂) id proj₁
interact-from-⊗ p₁ p₂ = record { stream≈ = helper (stream p₁) (stream p₂) }
where
helper : ∀ {O₁ O₂ C} (s₁ : Stream (O₁ × C)) (s₂ : Stream (O₂ × C)) →
≈-hetero (merge-stream s₁ s₂)
(map-stream transform (merge-stream s₁ s₂))
(comb id proj₁)
helper s₁ s₂ .head≈ = refl
helper s₁ s₂ .tail≈ = helper (Stream.tail s₁) (Stream.tail s₂)