Skip to content
Snippets Groups Projects
ClockProperties.agda 9.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • {-# OPTIONS --rewriting --guarded #-}
    
     -- to allow opening this module in other files while there are still holes
    {-# OPTIONS --allow-unsolved-metas #-}
    
    module Common.ClockProperties where
    
    open import Cubical.Foundations.Prelude
    open import Cubical.Foundations.Function
    open import Cubical.Data.Sum
    open import Cubical.Data.Sigma
    open import Cubical.Data.Bool hiding (_≤_)
    open import Cubical.Relation.Nullary
    open import Cubical.Data.Unit
    
    open import Cubical.Foundations.Isomorphism
    
    open import Common.Common
    open import Common.Later
    
    open import Agda.Builtin.Equality renaming (_≡_ to _≣_) hiding (refl)
    open import Agda.Builtin.Equality.Rewrite
    open import Cubical.Data.Equality.Conversion hiding (Iso ; funExt)
    -- open import Cubical.Data.Prod
    
    private
      variable
        ℓ ℓ' : Level
    
    
    {- remove -}
    
    -- Rewriting axioms used in the proofs:
    
    path-clock-irrel-bool-1 : {k k' : Clock} -> (b : Bool) ->
      bool-clock-irrel (λ _ -> b) k k' ≡ refl
    path-clock-irrel-bool-1 b = isSetBool b b _ refl
    
    rewrite-clock-irrel-bool-1 : {k k' : Clock} -> (b : Bool) ->
      bool-clock-irrel (λ _ -> b) k k' ≣ refl
    rewrite-clock-irrel-bool-1 {k = k} {k' = k'} b =
      pathToEq (path-clock-irrel-bool-1 b)
    -- clock-irrel-beta-const bool-clock-irrel b k k'
    
    path-clock-irrel-bool-2 :
        (M : Clock -> Bool) -> bool-clock-irrel M k0 k0 ≡ refl
    path-clock-irrel-bool-2 M =
      isSetBool (M k0) (M k0) (bool-clock-irrel M k0 k0) refl
    
    rewrite-clock-irrel-bool-2 :
        (M : Clock -> Bool) -> bool-clock-irrel M k0 k0 ≣ refl
    rewrite-clock-irrel-bool-2 M =
      pathToEq (path-clock-irrel-bool-2 M)
    -- clock-irrel-beta-k0 bool-clock-irrel
    
    rewrite-force : ∀ {ℓ : Level} -> {A : Clock -> Type ℓ} (f : ∀ k -> A k) →
      force' (λ k -> next (f k)) ≣ f
    rewrite-force f = pathToEq (force'-beta f)
    
    rewrite-transp : ∀ {ℓ : Level} {X : Type ℓ} →
      transp (λ i → X) i0 ≣ id
    rewrite-transp = pathToEq (funExt (λ x -> transportRefl x))
    
    {-# REWRITE rewrite-clock-irrel-bool-1 #-}
    
    {-# REWRITE rewrite-clock-irrel-bool-2 #-}
    
    {-# REWRITE rewrite-force #-}
    
    {-# REWRITE rewrite-transp #-}
    
    
    {- end remove -}
    
    {- Iso definitions used in this file:
    
     _Iso⟨_⟩_  : {ℓ ℓ' ℓ'' : Level} {B : Type ℓ'} {C : Type ℓ''}
                  (X : Type ℓ) →
                  Iso X B → Iso B C → Iso X C
      _∎Iso     : {ℓ : Level} (A : Type ℓ) → Iso A A
    
    
       Σ-Π-Iso   : {ℓ ℓ' ℓ'' : Level} {A : Type ℓ} {B : A → Type ℓ'}
                  {C : (a : A) → B a → Type ℓ''} →
                  Iso ((a : A) → Σ-syntax (B a) (C a))
                      (Σ-syntax ((a : A) → B a) (λ f → (a : A) → C a (f a)))
    
       codomainIsoDep
                : {ℓ ℓ' ℓ'' : Level} {A : Type ℓ} {B : A → Type ℓ'}
                  {C : A → Type ℓ''} →
                  ((a : A) → Iso (B a) (C a)) → Iso ((a : A) → B a) ((a : A) → C a)
    
       ⊎Iso      : {A.ℓa : Level} {A : Type A.ℓa} {C.ℓc : Level}
                  {C : Type C.ℓc} {B.ℓb : Level} {B : Type B.ℓb} {D.ℓd : Level}
                  {D : Type D.ℓd} →
                  Iso A C → Iso B D → Iso (A ⊎ B) (C ⊎ D)
    
      Σ-cong-iso-fst
                : {A.ℓ : Level} {A : Type A.ℓ} {B..1 : Level} {A' : Type B..1}
                  {B.ℓ : Level} {B : A' → Type B.ℓ} (isom : Iso A A') →
                  Iso (Σ A (B ∘ Iso.fun isom)) (Σ A' B)
    
      Σ-cong-iso-snd
                : {B'..1 : Level} {A : Type B'..1} {B.ℓ : Level} {B : A → Type B.ℓ}
                  {B'.ℓ : Level} {B' : A → Type B'.ℓ} →
                  ((x : A) → Iso (B x) (B' x)) → Iso (Σ A B) (Σ A B')
    
    -}
    
    
    -- The unit type is clock-irrelevant.
    Unit-clock-irrel : clock-irrel Unit
    Unit-clock-irrel M k k' with M k | M k'
    ...  | tt | tt = refl
    
    
    
    bool2ty : Type ℓ -> Type ℓ -> Bool -> Type ℓ
    bool2ty A B true = A
    bool2ty A B false = B
    
    bool2ty-eq : {X : Type ℓ} {A B : X -> Type ℓ'} ->
      (b : Bool) ->
      (∀ (x : X) -> bool2ty (A x) (B x) b) ≡
      bool2ty (∀ x -> A x) (∀ x -> B x) b
    bool2ty-eq {X} {A} {B} true = refl
    bool2ty-eq {X} {A} {B} false = refl
    
    bool2ty-A-A : (A : Type ℓ) (b : Bool) -> bool2ty A A b ≡ A
    bool2ty-A-A A true = refl
    bool2ty-A-A A false = refl
    
    
    Iso-⊎-ΣBool : {A B : Type ℓ} -> Iso (A ⊎ B) (Σ Bool (λ b -> bool2ty A B b))
    Iso-⊎-ΣBool {A = A} {B = B} = iso to inv sec retr
      where
        to : A ⊎ B → Σ Bool (λ b -> bool2ty A B b)
        to (inl a) = true , a
        to (inr b) = false , b
    
        inv : Σ Bool (bool2ty A B) → A ⊎ B
        inv (true , a) = inl a
        inv (false , b) = inr b
    
        sec : section to inv
        sec (true , a) = refl
        sec (false , b) = refl
    
        retr : retract to inv
        retr (inl a) = refl
        retr (inr b) = refl
    
    
    
    ∀clock-Σ : {A : Type} -> {B : A -> Clock -> Type} ->
        clock-irrel A ->
        (∀ (k : Clock) -> Σ A (λ a -> B a k)) ->
        Σ A (λ a -> ∀ (k : Clock) -> B a k)
    ∀clock-Σ {A} {B} H-clk-irrel p =
        let a = fst (p k0) in
          a , (λ k -> transport
                       (λ i → B (H-clk-irrel (fst ∘ p) k k0 i) k)
                       (snd (p k)))
      -- NTS:  B (fst (p k)) k ≡ B (fst (p k0)) k
      -- i.e. essentially need to show that fst (p k) ≡ fst (p k0)
      -- This follows from clock irrelevance for A, with M = fst ∘ p of type Clock -> A
    
    
    
    
    Dist-Pi-Sigma : {S : Type} -> {A : S -> Type} -> {B : (s : S) -> A s -> Type} ->
      Iso (∀ (s : S) -> (Σ[ x ∈ A s ] B s x))
          (Σ[ x ∈ (∀ s -> A s) ] ( ∀ s -> B s (x s) ))
    Dist-Pi-Sigma = Σ-Π-Iso
    
    -- Turn an equality into an iso.
    Eq-Iso : {A B : Type ℓ} ->
      A ≡ B -> Iso A B
    Eq-Iso {A = A} {B = B} H-eq = subst (Iso A) H-eq idIso
    -- same as: transport (cong (Iso A) H-eq) idIso
    
    
    -- Clock quantification distributes over products.
    Iso-∀clock-× : {A B : Clock → Type ℓ} →
      Iso (∀ k → A k × B k) ((∀ k → A k) × (∀ k → B k))
    Iso.fun Iso-∀clock-× f = (λ k → f k .fst) , (λ k → f k .snd)
    Iso.inv Iso-∀clock-× (f , g) = λ k → f k , g k
    Iso.rightInv Iso-∀clock-× (f , g) = refl
    Iso.leftInv Iso-∀clock-× f = refl
    
    
    
    -- Clock quantification distributes over sigma types.
    -- This is simply an instance of the usual distributivity
    -- of pi-types over sigma types.
    ∀k-Σ : {A : Clock → Type ℓ} → {B : (k : Clock) → A k → Type ℓ'} →
      Iso
        (∀ (k : Clock) → Σ (A k) (λ a → B k a))
        (Σ (∀ k → A k) (λ f → ∀ k → B k (f k)))
    ∀k-Σ {A = A} {B = B} = Σ-Π-Iso {A = Clock} {B = A} {C = B}
    
    
    -- Special case where the first type in the sigma is
    -- clock-irrelevant.
    Iso-∀clock-Σ : {A : Type ℓ} -> {B : A -> Clock -> Type ℓ'} ->
      clock-irrel A ->
      Iso
        (∀ (k : Clock) -> Σ A (λ a -> B a k))
        (Σ A (λ a -> ∀ (k : Clock) -> B a k))
    Iso-∀clock-Σ {A = A} {B = B} H-clk-irrel =
      (∀ (k : Clock) -> Σ A (λ a -> B a k))
         Iso⟨ Σ-Π-Iso {A = Clock} {B = λ k -> A} {C = λ k a -> B a k} ⟩
         
      (Σ ((k : Clock) → A) (λ f → (k : Clock) → B (f k) k))
         Iso⟨ ( Σ-cong-iso-snd (λ f → codomainIsoDep (λ k → Eq-Iso (λ i → B (H-clk-irrel f k k0 i) k)))) ⟩
    
      (Σ ((k : Clock) → A) (λ f → (k : Clock) → B (f k0) k))
         Iso⟨ Σ-cong-iso-fst {B = λ a -> ∀ k' -> B a k'} (Iso-∀kA-A H-clk-irrel) ⟩
         
      (Σ A (λ a -> ∀ (k : Clock) -> B a k)) ∎Iso
    
    {- Note:
              Σ-cong-iso-fst
                : {A.ℓ : Level} {A : Type A.ℓ} {B..1 : Level} {A' : Type B..1}
                  {B.ℓ : Level} {B : A' → Type B.ℓ} (isom : Iso A A') →
                  Iso (Σ A (B ∘ Iso.fun isom)) (Σ A' B)
    
        In this case, the isomorphism function associated with Iso-∀kA-A
        takes f : (∀ (k : Clock) -> A) to A by applying f to k0.
        This is why we need the intermediate step of transforming B (f k) k
        into B (f k0) k.
    
    -}
    
    
    -- Action of the above isomorphism
    Iso-∀clock-Σ-fun : {A : Type ℓ} {B : A -> Clock -> Type ℓ'} ->
      (H : clock-irrel A) ->
      (f : (k : Clock) -> Σ A (λ a -> B a k)) ->
      Iso.fun (Iso-∀clock-Σ {A = A} {B = B} H) f ≡ (fst (f k0) , λ k -> {!f k .snd!})
    Iso-∀clock-Σ-fun {A = A} {B = B} H f = ΣPathP (refl , (funExt (λ k -> {!!} ∙ {!!})))
    
    
    -- Clock quantification distributes over coproducts.
    Iso-Π-⊎-clk : {A B : Clock -> Type ℓ} ->
      Iso
        ((k : Clock) -> (A k ⊎ B k))
        (((k : Clock) -> A k) ⊎ ((k : Clock) -> B k))
    Iso-Π-⊎-clk {A = A} {B = B} =
      (∀ (k : Clock) -> (A k ⊎ B k))
        Iso⟨ codomainIsoDep (λ k -> Iso-⊎-ΣBool) ⟩
      (∀ (k : Clock) -> Σ[ b ∈ Bool ] bool2ty (A k) (B k) b )
        Iso⟨ Iso-∀clock-Σ bool-clock-irrel ⟩
      (Σ[ b ∈ Bool ] ∀ k -> bool2ty (A k) (B k) b)
        Iso⟨ Σ-cong-iso-snd (λ b → Eq-Iso (bool2ty-eq b)) ⟩
        --  (cong (Iso ((x : Clock) → bool2ty (A x) (B x) b)) (bool2ty-eq b))
      (Σ[ b ∈ Bool ] bool2ty (∀ k -> A k) (∀ k -> B k) b)
        Iso⟨ invIso Iso-⊎-ΣBool ⟩
      (∀ k -> A k) ⊎ (∀ k -> B k) ∎Iso
    
    -- Action of the above isomorphism
    Iso-Π-⊎-clk-fun : {A B : Clock -> Type} -> {f : (k : Clock) -> (A k ⊎ B k) } ->
      (H : ∀ k -> Σ[ a ∈ A k ] f k ≡ inl a) ->
      Iso.fun Iso-Π-⊎-clk f ≡ inl λ k -> H k .fst
    Iso-Π-⊎-clk-fun {A} {B} {f} H = {!!}
    
    Iso-Π-⊎-clk-inv-inl : {A B : Clock -> Type} ->
      {f : (k : Clock) → A k} ->
      Iso.inv (Iso-Π-⊎-clk {B = B}) (inl f) ≡ λ k -> inl (f k)
    Iso-Π-⊎-clk-inv-inl {A = A} {B = B} {f = f} = funExt (λ k → cong inl {!!})
    -- (s : ((k : Clock) → A k) ⊎ ((k : Clock) → B k)) ->
    
    -- transport p a = transp (λ i → p i) i0 a
    --
    -- transp (λ i → A (transp (λ j → Clock) i k)) i0 (transp (λ i → A (transp (λ j → Clock) i k)) i0 (f k))
    
    -- transport (λ i → A (transp (λ j → Clock) i k))
    
    test :  {A B : Clock -> Type ℓ} → (((k : Clock) -> A k) ⊎ ((k : Clock) -> B k)) → ((k : Clock) -> (A k ⊎ B k))
    test (inl f) k = inl (f k)
    test (inr g) k = inr (g k)
    
    test' :  {A B : Clock -> Type ℓ} → ((k : Clock) -> (A k ⊎ B k)) → (((k : Clock) -> A k) ⊎ ((k : Clock) -> B k))
    test' {A = A} {B = B} f = aux (f k0)
      where
        aux : A k0 ⊎ B k0 → _
        aux (inl a) = inl (λ k → {!!})
        aux (inr b) = inr (λ k → {!!})