{-# OPTIONS --exact-split #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K #-}
module FOTC.Program.ABP.Fair.PropertiesI where
open import Common.FOL.Relation.Binary.EqReasoning
open import FOTC.Base
open import FOTC.Base.List
open import FOTC.Base.List.PropertiesI
open import FOTC.Data.List
open import FOTC.Data.List.PropertiesI
open import FOTC.Data.Stream.Type
open import FOTC.Program.ABP.Fair.Type
open import FOTC.Program.ABP.Terms
Fair-in : ∀ {os} → ∃[ ft ] ∃[ os' ] F*T ft ∧ os ≡ ft ++ os' ∧ Fair os' →
Fair os
Fair-in h = Fair-coind A h' h
where
A : D → Set
A os = ∃[ ft ] ∃[ os' ] F*T ft ∧ os ≡ ft ++ os' ∧ Fair os'
h' : ∀ {os} → A os → ∃[ ft ] ∃[ os' ] F*T ft ∧ os ≡ ft ++ os' ∧ A os'
h' (ft , os' , FTft , prf , Fos') = ft , os' , FTft , prf , Fair-out Fos'
head-tail-Fair : ∀ {os} → Fair os → os ≡ T ∷ tail₁ os ∨ os ≡ F ∷ tail₁ os
head-tail-Fair {os} Fos with Fair-out Fos
... | .(T ∷ []) , os' , f*tnil , h , Fos' = inj₁ prf₃
where
prf₁ : os ≡ T ∷ [] ++ os'
prf₁ = os ≡⟨ h ⟩
(T ∷ []) ++ os' ≡⟨ ++-∷ T [] os' ⟩
T ∷ [] ++ os' ∎
prf₂ : tail₁ os ≡ [] ++ os'
prf₂ = tail₁ os ≡⟨ tailCong prf₁ ⟩
tail₁ (T ∷ [] ++ os') ≡⟨ tail-∷ T ([] ++ os') ⟩
[] ++ os' ∎
prf₃ : os ≡ T ∷ tail₁ os
prf₃ = os ≡⟨ prf₁ ⟩
T ∷ [] ++ os' ≡⟨ ∷-rightCong (sym prf₂) ⟩
T ∷ tail₁ os ∎
... | .(F ∷ ft) , os' , f*tcons {ft} FTft , h , Fos' =
inj₂ prf₃
where
prf₁ : os ≡ F ∷ ft ++ os'
prf₁ = os ≡⟨ h ⟩
(F ∷ ft) ++ os' ≡⟨ ++-∷ F ft os' ⟩
F ∷ ft ++ os' ∎
prf₂ : tail₁ os ≡ ft ++ os'
prf₂ = tail₁ os ≡⟨ tailCong prf₁ ⟩
tail₁ (F ∷ ft ++ os') ≡⟨ tail-∷ F (ft ++ os') ⟩
ft ++ os' ∎
prf₃ : os ≡ F ∷ tail₁ os
prf₃ = os ≡⟨ prf₁ ⟩
F ∷ ft ++ os' ≡⟨ ∷-rightCong (sym prf₂) ⟩
F ∷ tail₁ os ∎
tail-Fair : ∀ {os} → Fair os → Fair (tail₁ os)
tail-Fair {os} Fos with Fair-out Fos
... | .(T ∷ []) , os' , f*tnil , h , Fos' =
subst Fair (sym prf₂) Fos'
where
prf₁ : os ≡ T ∷ os'
prf₁ = os ≡⟨ h ⟩
(T ∷ []) ++ os' ≡⟨ ++-∷ T [] os' ⟩
T ∷ [] ++ os' ≡⟨ ∷-rightCong (++-leftIdentity os') ⟩
T ∷ os' ∎
prf₂ : tail₁ os ≡ os'
prf₂ = tail₁ os ≡⟨ tailCong prf₁ ⟩
tail₁ (T ∷ os') ≡⟨ tail-∷ T os' ⟩
os' ∎
... | .(F ∷ ft) , os' , f*tcons {ft} FTft , h , Fos' =
subst Fair (sym prf₂) (Fair-in (ft , os' , FTft , refl , Fos'))
where
prf₁ : os ≡ F ∷ ft ++ os'
prf₁ = os ≡⟨ h ⟩
(F ∷ ft) ++ os' ≡⟨ ++-∷ F ft os' ⟩
F ∷ ft ++ os' ∎
prf₂ : tail₁ os ≡ ft ++ os'
prf₂ = tail₁ os ≡⟨ tailCong prf₁ ⟩
tail₁ (F ∷ ft ++ os') ≡⟨ tail-∷ F (ft ++ os') ⟩
ft ++ os' ∎
Fair→Stream : ∀ {os} → Fair os → Stream os
Fair→Stream Fos = Stream-coind A h Fos
where
A : D → Set
A xs = Fair xs
h : ∀ {os} → A os → ∃[ o' ] ∃[ os' ] os ≡ o' ∷ os' ∧ A os'
h {os} As with head-tail-Fair As
... | inj₁ prf = T , tail₁ os , prf , tail-Fair As
... | inj₂ prf = F , tail₁ os , prf , tail-Fair As
F*T→List : ∀ {xs} → F*T xs → List xs
F*T→List f*tnil = lcons T lnil
F*T→List (f*tcons {ft} FTft) = lcons F (F*T→List FTft)