-- Andreas, 2017-10-17, issue #2807
--
-- Refining with an extended lambda gave internal error.
-- Seemed to be triggered only when giving resulted in an error.

{-# OPTIONS --allow-unsolved-metas #-}

-- {-# OPTIONS -v scope.extendedLambda:60 #-}
-- {-# OPTIONS -v impossible:10 #-}

data ⊥ : Set where
  actuallyNotEmpty : ⊥

data D : Set where
  c : ⊥ → D

test : D → ⊥
test = {! λ{ (c ()) }!}  -- C-c C-r

-- WAS: internal error in ConcreteToAbstract (insertApp)
--
-- Expected:
-- Succeed with unsolved constraints and metas.


{-# OPTIONS --no-qualified-instances #-}

module NoQualifiedInstances-InAnonymousModule where

postulate
  A : Set
  f : {{A}} → A

module _ where postulate instance a : A

test : A
test = f


{-# OPTIONS --without-K #-}

open import Base

module Homotopy.VanKampen.Guide where

open import Homotopy.Truncation
open import Homotopy.Connected

record legend i (city : Set i) : Set (suc i) where
  constructor leg_,_,_
  field
    name : Set i
    loc : name → city
    all-listed : ∀ c → [ hfiber loc c ]

id-legend : ∀ {i} (A : Set i) → legend i A
id-legend A = leg A , id A , λ x → proj $ x , refl

private
  module Book {i} {city : Set i} {l : legend i city} where
    open legend l

    private
      data #guide : Set i where
        #point : name → #guide

    guide : Set i
    guide = #guide

    point : name → guide
    point = #point

    postulate  -- HIT
      route : ∀ n₁ n₂ → loc n₁ ≡ loc n₂ → point n₁ ≡ point n₂

    guide-rec : ∀ {l} (P : guide → Set l)
      (point* : (n : name) → P (point n))
      (route* : ∀ n₁ n₂ (p : loc n₁ ≡ loc n₂)
        → transport P (route n₁ n₂ p) (point* n₁) ≡ point* n₂)
      → (x : guide) → P x
    guide-rec P point* route* (#point n) = point* n

    postulate  -- HIT
      guide-β-route : ∀ {l} (P : guide → Set l)
        (point* : (n : name) → P (point n))
        (route* : ∀ n₁ n₂ (p : loc n₁ ≡ loc n₂)
          → transport P (route n₁ n₂ p) (point* n₁) ≡ point* n₂)
        n₁ n₂ (p : loc n₁ ≡ loc n₂)
        → apd (guide-rec {l} P point* route*) (route n₁ n₂ p)
        ≡ route* n₁ n₂ p

    guide-rec-nondep : ∀ {l} (P : Set l) (point* : name → P)
      (route* : ∀ n₁ n₂ → loc n₁ ≡ loc n₂ → point* n₁ ≡ point* n₂)
      → (guide → P)
    guide-rec-nondep P point* route* (#point n) = point* n

    postulate  -- HIT
      guide-β-route-nondep : ∀ {l} (P : Set l) (point* : name → P)
        (route* : ∀ n₁ n₂ → loc n₁ ≡ loc n₂ → point* n₁ ≡ point* n₂)
        n₁ n₂ (p : loc n₁ ≡ loc n₂)
        → ap (guide-rec-nondep P point* route*) (route n₁ n₂ p)
        ≡ route* n₁ n₂ p

open Book public hiding (guide)

module _ {i} {city : Set i} (l : legend i city) where
  open legend l

  guide : Set i
  guide = Book.guide {i} {city} {l}

  visit : guide → city
  visit = guide-rec-nondep city loc (λ _ _ p → p)

  visit-β-route : ∀ n₁ n₂ (p : loc n₁ ≡ loc n₂) → ap visit (route n₁ n₂ p) ≡ p
  visit-β-route = guide-β-route-nondep city loc (λ _ _ p → p)

  private
    drawn-as-one : ∀ c → is-contr (π₀ $ hfiber visit c)
    drawn-as-one c = []-extend-nondep
      ⦃ is-connected-is-prop ⟨0⟩ ⦄
      ( λ {(n₁ , p₁) → proj (point n₁ , p₁) , π₀-extend
        ⦃ λ _ → ≡-is-set $ π₀-is-set $ hfiber visit c ⦄
        ( uncurry $ guide-rec
          (λ x → ∀ p₂ → proj (x , p₂) ≡ proj (point n₁ , p₁))
          (λ n₂ p₂ → ap proj let p₃ = p₂ ∘ ! p₁ in
            Σ-eq (route n₂ n₁ p₃) $
              transport (λ x → visit x ≡ c) (route n₂ n₁ p₃) p₂
                ≡⟨ trans-app≡cst visit c (route n₂ n₁ p₃) p₂ ⟩
              ! (ap visit (route n₂ n₁ p₃)) ∘ p₂
                ≡⟨ ap (λ x → ! x ∘ p₂) $ visit-β-route n₂ n₁ p₃ ⟩
              ! (p₂ ∘ ! p₁) ∘ p₂
                ≡⟨ ap (λ x → x ∘ p₂) $ opposite-concat p₂ (! p₁) ⟩
              (! (! p₁) ∘ ! p₂) ∘ p₂
                ≡⟨ concat-assoc (! (! p₁)) (! p₂) p₂ ⟩
              ! (! p₁) ∘ (! p₂ ∘ p₂)
                ≡⟨ ap (λ x → ! (! p₁) ∘ x) $ opposite-left-inverse p₂ ⟩
              ! (! p₁) ∘ refl
                ≡⟨ refl-right-unit $ ! (! p₁) ⟩
              ! (! p₁)
                ≡⟨ opposite-opposite p₁ ⟩∎
              p₁
                ∎)
          (λ _ _ _ → funext λ _ → prop-has-all-paths (π₀-is-set _ _ _) _ _))})
      (all-listed c)

  private
    visit-fiber-rec′ : ∀ {j} (P : city → Set j)
      (h₀-point : ∀ n → P (loc n))
      (h₁-route : ∀ n₁ n₂ r → transport P r (h₀-point n₁) ≡ h₀-point n₂)
      → (∀ c → hfiber visit c → P c)
    visit-fiber-rec′ P h₀-p h₁-r c (pt , p₁) =
      transport P p₁ $ guide-rec (P ◯ visit) h₀-p
        (λ n₁ n₂ r →
            transport (P ◯ visit) (route n₁ n₂ r) (h₀-p n₁)
              ≡⟨ ! $ trans-ap P visit (route n₁ n₂ r) $ h₀-p n₁ ⟩
            transport P (ap visit $ route n₁ n₂ r) (h₀-p n₁)
              ≡⟨ ap (λ x → transport P x $ h₀-p n₁) $ visit-β-route n₁ n₂ r ⟩
            transport P r (h₀-p n₁)
              ≡⟨ h₁-r n₁ n₂ r ⟩∎
            h₀-p n₂
              ∎) pt

  visit-fiber-rec : ∀ {j} (P : city → Set j)
    ⦃ _ : ∀ (c : city) → is-set $ P c ⦄
    (h₀-point : ∀ n → P (loc n))
    (h₁-route : ∀ n₁ n₂ r → transport P r (h₀-point n₁) ≡ h₀-point n₂)
    → (∀ c → P c)
  visit-fiber-rec P ⦃ P-is-set ⦄ h₀-p h₁-r c =
    π₀-extend-nondep ⦃ P-is-set c ⦄
    (visit-fiber-rec′ P h₀-p h₁-r c)
    (π₁ $ drawn-as-one c)

  visit-fiber-β-loc : ∀ {j} (P : city → Set j)
    ⦃ P-is-set : ∀ (c : city) → is-set $ P c ⦄
    (h₀-p : ∀ n → P (loc n))
    (h₁-r : ∀ n₁ n₂ r → transport P r (h₀-p n₁) ≡ h₀-p n₂)
    → ∀ n → visit-fiber-rec P ⦃ P-is-set ⦄ h₀-p h₁-r (loc n) ≡ h₀-p n
  visit-fiber-β-loc P ⦃ P-is-set ⦄ h₀-p h₁-r n =
    visit-fiber-rec P ⦃ P-is-set ⦄ h₀-p h₁-r (loc n)
      ≡⟨ ap (π₀-extend-nondep ⦃ P-is-set $ loc n ⦄ (visit-fiber-rec′ P h₀-p h₁-r $ loc n))
            $ ! $ π₂ (drawn-as-one $ loc n) (proj $ point n , refl) ⟩∎
    h₀-p n
      ∎

  private
    loc-fiber-rec′ : ∀ {j} (P : city → Set j)
      (h₀-point : ∀ n → P (loc n))
      → (∀ c → hfiber loc c → P c)
    loc-fiber-rec′ P h₀-p c (n , p) = transport P p (h₀-p n)

  loc-fiber-rec : ∀ {j} (P : city → Set j)
    ⦃ _ : ∀ c → is-prop $ P c ⦄
    (h₀-point : ∀ n → P (loc n))
    → (∀ c → P c)
  loc-fiber-rec P ⦃ P-is-prop ⦄ h₀-p c = []-extend-nondep ⦃ P-is-prop c ⦄
    (loc-fiber-rec′ P h₀-p c) (all-listed c)

  loc-fiber-β-loc : ∀ {j} (P : city → Set j)
    ⦃ P-is-prop : ∀ (c : city) → is-prop $ P c ⦄
    (h₀-p : ∀ n → P (loc n))
    → ∀ n → loc-fiber-rec P ⦃ P-is-prop ⦄ h₀-p (loc n) ≡ h₀-p n
  loc-fiber-β-loc P ⦃ P-is-prop ⦄ h₀-p n =
    loc-fiber-rec P ⦃ P-is-prop ⦄ h₀-p (loc n)
      ≡⟨ ap ([]-extend-nondep ⦃ P-is-prop $ loc n ⦄ (loc-fiber-rec′ P h₀-p $ loc n))
            $ prop-has-all-paths []-is-prop (all-listed $ loc n) $ proj $ n , refl ⟩∎
    h₀-p n
      ∎

-- Did I preserve the computational contents for identity legend?
private
  module IdTest {i} {city : Set i} where
    open legend (id-legend city)

    visit-fiber-β-id : ∀ {j} (P : city → Set j)
      ⦃ P-is-set : ∀ (c : city) → is-set $ P c ⦄
      (h₀-p : ∀ n → P n)
      (h₁-r : ∀ n₁ n₂ r → transport P r (h₀-p n₁) ≡ h₀-p n₂)
      → ∀ n → visit-fiber-rec (id-legend city) P ⦃ P-is-set ⦄ h₀-p h₁-r n ≡ h₀-p n
    visit-fiber-β-id P ⦃ P-is-set ⦄ h₀-p h₁-r n = refl

    loc-fiber-β-id : ∀ {j} (P : city → Set j)
      ⦃ P-is-prop : ∀ (c : city) → is-prop $ P c ⦄
      (h₀-p : ∀ n → P n)
      → ∀ n → loc-fiber-rec (id-legend city) P ⦃ P-is-prop ⦄ h₀-p n ≡ h₀-p n
    loc-fiber-β-id P ⦃ P-is-prop ⦄ h₀-p n = refl


module FFI.IO where

import      Lvl
open import Data
open import String
open import Type

postulate IO : ∀{a} → Type{a} → Type{a}
{-# BUILTIN IO IO #-}
{-# FOREIGN GHC type AgdaIO a b = IO b #-}
{-# COMPILE GHC IO = type AgdaIO #-}

{-# FOREIGN GHC import qualified Data.Text.IO #-}

postulate printStr : String → IO(Unit{Lvl.𝟎})
{-# COMPILE GHC printStr = Data.Text.IO.putStr #-}

postulate printStrLn : String → IO(Unit{Lvl.𝟎})
{-# COMPILE GHC printStrLn = Data.Text.IO.putStrLn #-}


-- Soundness of term equality
module Semantics.Soundness where

open import Syntax.Types
open import Syntax.Context renaming (_,_ to _,,_)
open import Syntax.Terms
open import Syntax.Equality
open import Syntax.Substitution

open import Semantics.Types
open import Semantics.Context
open import Semantics.Terms
open import Semantics.Substitution
open import Semantics.Bind

open import CategoryTheory.Categories using (ext)
open import CategoryTheory.BCCCs.Cartesian using (Product)
open import CategoryTheory.BCCCs
open import CategoryTheory.Instances.Reactive renaming (top to Top)
open import CategoryTheory.NatTrans
open import CategoryTheory.Monad
open import TemporalOps.Diamond
open import TemporalOps.OtherOps

open import Data.Sum
open import Data.Product using (_,_ ; proj₁ ; proj₂)
open import Relation.Binary.PropositionalEquality as ≡
    using (_≡_ ; refl ; sym ; trans ; cong ; cong₂ ; subst)

open ≡.≡-Reasoning
open Monad M-◇
open import Holes.Term using (⌞_⌟)
open import Holes.Cong.Propositional

open ⟦Kit⟧ ⟦𝒯erm⟧
open Kit 𝒯erm
open ⟦K⟧ ⟦𝒯erm⟧
open K 𝒯erm

mutual
    -- Soundness of term equality: equal terms have equal denotations
    sound : ∀{A Γ} {M₁ M₂ : Γ ⊢ A}
             -> Γ ⊢ M₁ ≡ M₂ ∷ A
             -> ⟦ M₁ ⟧ₘ ≈ ⟦ M₂ ⟧ₘ
    sound (refl M) = refl
    sound (Eq.sym eq) = ≡.sym (sound eq)
    sound (Eq.trans eq₁ eq₂) = ≡.trans (sound eq₁) (sound eq₂)

    sound (β-lam N M) {n} {⟦Γ⟧} rewrite subst-sound M N {n} {⟦Γ⟧} = refl
    sound (β-fst M N) = refl
    sound (β-snd M N) = refl
    sound (β-inl M N₁ N₂) {n} {⟦Γ⟧} rewrite subst-sound M N₁ {n} {⟦Γ⟧} = refl
    sound (β-inr M N₁ N₂) {n} {⟦Γ⟧} rewrite subst-sound M N₂ {n} {⟦Γ⟧} = refl
    sound (β-sig N M) {n} {⟦Γ⟧} rewrite subst-sound M N {n} {⟦Γ⟧} = refl

    sound (η-lam {A} M) {n} {⟦Γ⟧} = ext λ ⟦A⟧ →
                        cong (λ x → x ⟦A⟧) (≡.sym (⟦𝓌⟧ (A now) M {n} {⟦Γ⟧ , ⟦A⟧}))
    sound (η-pair M) = ≡.sym (⊗-η-exp {m = ⟦ M ⟧ₘ})
    sound (η-unit M) = refl
    sound (η-sum M) {n} {⟦Γ⟧} with ⟦ M ⟧ₘ n ⟦Γ⟧
    sound (η-sum M) {n} {a} | inj₁ _ = refl
    sound (η-sum M) {n} {a} | inj₂ _ = refl
    sound (η-sig M) = refl
    sound {Γ = Γ} (η-evt {A} M) {n} {a}
        rewrite bind-to->>= Γ (⟦ M ⟧ₘ) (η.at ⟦ A ⟧ₜ ∘ π₂) n a
              = ≡.sym (>>=-unit-right (⟦ M ⟧ₘ n a))

    sound (cong-pair eq₁ eq₂) {n} {a} rewrite sound eq₁ {n} {a}
                                            | sound eq₂ {n} {a} = refl
    sound (cong-fst eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-snd eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-lam eq) {n} {a} = ext λ ⟦A⟧ → sound eq
    sound (cong-app eq₁ eq₂) {n} {a} rewrite sound eq₁ {n} {a}
                                           | sound eq₂ {n} {a} = refl
    sound (cong-inl eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-inr eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-case eq N₁ N₂) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-sig eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-letSig eq N) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-sample eq) {n} {a} rewrite sound eq {n} {a} = refl
    sound (cong-stable eq) = ext λ k → sound eq
    sound (cong-event eq) {n} {a} rewrite sound′ eq {n} {a} = refl

    -- Soundness of computational term equality: equal terms have equal denotations
    sound′ : ∀{A Γ} {M₁ M₂ : Γ ⊨ A}
             -> Γ ⊨ M₁ ≡ M₂ ∷ A
             -> ⟦ M₁ ⟧ᵐ ≈ ⟦ M₂ ⟧ᵐ
    sound′ (refl M) = refl
    sound′ (Eq′.sym eq) = ≡.sym (sound′ eq)
    sound′ (Eq′.trans eq₁ eq₂) = ≡.trans (sound′ eq₁) (sound′ eq₂)
    sound′ (β-sig′ C M) {n} {⟦Γ⟧} rewrite subst′-sound M C {n} {⟦Γ⟧} = refl
    sound′ (β-evt′ C D) {n} {⟦Γ⟧} rewrite subst″-sound D C {n} {⟦Γ⟧} = refl
    sound′ {_}{Γ} (β-selectₚ {A}{B}{C} C₁ C₂ C₃ M₁ M₂) {n} {⟦Γ⟧} =
        begin
            ⟦ select event (pure M₁) ↦ C₁ || event (pure M₂) ↦ C₂ ||both↦ C₃ ⟧ᵐ n ⟦Γ⟧
        ≡⟨⟩
            ⟦ C₃ ⟧ᵐ n ((⌞ ⟦ Γ ˢ⟧□ n ⟦Γ⟧ n ⌟ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⟦ M₂ ⟧ₘ n ⟦Γ⟧)
        ≡⟨ cong! (⟦ˢ⟧-factor Γ {n} {⟦Γ⟧}) ⟩
            ⟦ C₃ ⟧ᵐ n ((⌞ ⟦ Γ ˢ⟧ n ⟦Γ⟧ ⌟ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⟦ M₂ ⟧ₘ n ⟦Γ⟧)
        ≡⟨ cong! (⟦subst⟧-Γˢ⊆Γ Γ {n} {⟦Γ⟧}) ⟩
            ⟦ C₃ ⟧ᵐ n (⌞ (⟦subst⟧ (Γˢ⊆Γ Γ ⊆ₛ 𝒯erm) n ⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) ⌟ , ⟦ M₂ ⟧ₘ n ⟦Γ⟧ )
        ≡⟨ cong! (⟦↑⟧ (A now) (Γˢ⊆Γ Γ ⊆ₛ 𝒯erm) {n} {⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧)}) ⟩
            ⟦ C₃ ⟧ᵐ n ⌞ ((⟦subst⟧ (_↑_ {A now} (Γˢ⊆Γ Γ ⊆ₛ 𝒯erm) 𝒯erm) n (⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧)) , ⟦ M₂ ⟧ₘ n ⟦Γ⟧) ⌟
        ≡⟨ cong! (⟦↑⟧ (B now) (_↑_ {A now} (Γˢ⊆Γ Γ ⊆ₛ 𝒯erm) 𝒯erm) {n} {(⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , (⟦ M₂ ⟧ₘ n ⟦Γ⟧)}) ⟩
            ⟦ C₃ ⟧ᵐ n (⟦subst⟧ (_↑_ {B now} (_↑_ {A now} (Γˢ⊆Γ Γ ⊆ₛ 𝒯erm) 𝒯erm) 𝒯erm) n ((⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⌞ ⟦ M₂ ⟧ₘ n ⟦Γ⟧ ⌟))
        ≡⟨ cong! (⟦𝓌⟧ (A now) M₂ {n} {⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧)}) ⟩
            ⟦ C₃ ⟧ᵐ n (⟦subst⟧ (weakₛ 𝒯ermₛ s) n ((⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⟦ 𝓌 M₂ ⟧ₘ n (⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧)))
        ≡⟨ ≡.sym (traverse′-sound ⟦𝒯erm⟧ (weakₛ 𝒯ermₛ s) C₃ {n} {(⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⟦ 𝓌 M₂ ⟧ₘ n (⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧))})  ⟩
            ⟦ traverse′ (weakₛ 𝒯ermₛ s) C₃ ⟧ᵐ n ((⟦Γ⟧ , ⟦ M₁ ⟧ₘ n ⟦Γ⟧) , ⟦ 𝓌 M₂ ⟧ₘ n (⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧)))
        ≡⟨ ≡.sym (subst′-sound (𝓌 M₂) (weakening′ s C₃) {n} {⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧)}) ⟩
            ⟦ [ 𝓌 M₂ /′] (weakening′ s C₃) ⟧ᵐ n (⟦Γ⟧ , (⟦ M₁ ⟧ₘ n ⟦Γ⟧))
        ≡⟨ ≡.sym (subst′-sound M₁ ([ 𝓌 M₂ /′] (weakening′ s C₃)) {n} {⟦Γ⟧} ) ⟩
            ⟦ [ M₁ /′] ([ 𝓌 M₂ /′] (weakening′ s C₃)) ⟧ᵐ n ⟦Γ⟧
        ∎
        where
        s : Γ ˢ ,, A now ,, B now ⊆ Γ ,, A now ,, B now
        s = keep (keep (Γˢ⊆Γ Γ))
    sound′ (η-sig′ M) = refl
    sound′ (cong-pure′ eq) {n} {⟦Γ⟧} rewrite sound eq {n} {⟦Γ⟧} = refl
    sound′ (cong-letSig′ eq B) {n} {⟦Γ⟧} rewrite sound eq {n} {⟦Γ⟧} = refl
    sound′ (cong-letEvt′ eq D) {n} {⟦Γ⟧} rewrite sound eq {n} {⟦Γ⟧} = refl


-- Andreas, 2019-12-03, issue #4205, reported by Smaug123,
-- first shrinking by Jesper Cockx

record R : Set₂ where
  field
    f : Set₁

postulate
  r : R

open R r

test : R
R.f test with Set₃
f test | _  = Set

-- WAS: internal error in getOriginalProjection

-- EXPECTED:
-- With clause pattern f is not an instance of its parent pattern R.f
-- when checking that the clause
-- R.f test with Set₃
-- f test | _ = Set
-- has type R


module SizedIO.Base where

open import Data.Maybe.Base
open import Data.Sum renaming (inj₁ to left; inj₂ to right; [_,_]′ to either)

open import Function
--open import Level using (_⊔_) renaming (suc to lsuc)
open import Size
open import Data.List
open import SizedIO.Object

open import NativeIO
open import Data.Product

record IOInterface  : Set₁ where
  field
    Command   : Set
    Response  : (m : Command) → Set
open IOInterface public

module _ (I : IOInterface ) (let C = Command I) (let R = Response I) where

  mutual
    record IO (i : Size)  (A : Set) : Set where
      coinductive
      constructor delay
      field
        force : {j : Size< i} → IO' j A

    data IO' (i : Size)  (A : Set) : Set where
      do'     : (c : C) (f : R c → IO i A) → IO' i A
      return' : (a : A) → IO' i A

  data IO+ (i : Size)  (A : Set) : Set where
    do' : (c : C) (f : R c → IO i A) → IO+ i A

open IO public

objectInterfToIOInterf : Interface → IOInterface
objectInterfToIOInterf I .Command = I .Method
objectInterfToIOInterf I .Response = I .Result

ioInterfToObjectInterf : IOInterface → Interface
ioInterfToObjectInterf I .Method = I .Command
ioInterfToObjectInterf I .Result = I .Response

module _  {I : IOInterface } (let C = Command I) (let R = Response I) where

  return : ∀{i}{A : Set} (a : A) → IO I i A
  return a .force = return' a

  do : ∀{i}{A : Set} (c : C) (f : R c → IO I i A) → IO I i A
  do c f .force = do' c f

  do1 :  ∀{i} (c : C) → IO I i (R c)
  do1 c = do c return

  infixl 2 _>>=_ _>>='_ _>>_

  mutual
    _>>='_ : ∀{i}{A B : Set}(m : IO' I i A) (k : A → IO I (↑ i) B) → IO' I i B
    do' c f    >>=' k = do' c λ x → f x >>= k
    return' a >>=' k = (k a) .force

    _>>=_ : ∀{i}{A B : Set}(m : IO I i A) (k : A → IO I i B) → IO I i B
    (m >>= k) .force = m .force >>=' k

  _>>_ : ∀{i}{B : Set} (m : IO I i Unit) (k : IO I i B) → IO I i B
  m >> k = m >>= λ _ → k

  {-# NON_TERMINATING #-}
  translateIO : ∀{A : Set}
    →  (translateLocal : (c : C) → NativeIO (R c))
    →  IO I ∞ A
    →  NativeIO A
  translateIO translateLocal m = case (m .force {_}) of
    λ{ (do' c f)    → (translateLocal c) native>>= λ r →
         translateIO translateLocal (f r)
     ; (return' a) → nativeReturn a
     }

  -- Recursion

  -- trampoline provides a generic form of loop (generalizing while/repeat).
  -- Starting at state s : S, step function f is iterated until it returns
  -- a result in A.

  fromIO+' : ∀{i}{A : Set} → IO+ I i A → IO' I i A
  fromIO+' (do' c f) = do' c f

  fromIO+ : ∀{i}{A : Set} → IO+ I i A → IO I i A
  fromIO+ (do' c f) .force = do' c f

  _>>=+'_ : ∀{i}{A B : Set}(m : IO+ I i A) (k : A → IO I i B) → IO' I i B
  do' c f >>=+' k = do' c λ x → f x >>= k

  _>>=+_ : ∀{i}{A B : Set}(m : IO+ I i A) (k : A → IO I i B) → IO I i B
  (m >>=+ k) .force = m >>=+' k

  mutual

    _>>+_ : ∀{i}{A B : Set}(m : IO I i (A ⊎ B)) (k : A → IO I i B) → IO I i B
    (m >>+ k) .force = m .force >>+' k

    _>>+'_ : ∀{j}{A B : Set} (m : IO' I j (A ⊎ B)) (k : A → IO I (↑ j) B) → IO' I j B
    do' c f            >>+' k = do' c λ x → f x >>+ k
    return' (left  a) >>+' k = k a .force
    return' (right b) >>+' k = return' b

   -- loop

  trampoline : ∀{i}{A S : Set} (f : S → IO+ I i (S ⊎ A)) (s : S) → IO I i A
  trampoline f s .force = case (f s) of
    \{ (do' c k) → do' c λ r → k r >>+ trampoline f }

  -- simple infinite loop

  forever : ∀{i}{A B : Set} → IO+ I i A → IO I i B
  forever (do' c f) .force = do' c λ r → f r >>= λ _ → forever (do' c f)

  whenJust : ∀{i}{A : Set} → Maybe A → (A → IO I i (Unit )) → IO I i Unit
  whenJust nothing  k = return _
  whenJust (just a) k = k a

mutual
  mapIO : ∀ {i} → {I : IOInterface} → {A B : Set} → (A → B) → IO I i  A  → IO I i B
  mapIO f p .force = mapIO' f (p .force)

  mapIO' : ∀ {i} → {I : IOInterface} → {A B : Set} → (A → B) → IO' I i  A  → IO' I i B
  mapIO' f (do' c g) = do' c (λ r → mapIO f (g r))
  mapIO' f (return' a) = return' (f a)

sequenceIO : {i : IOInterface} →  List  (IO  i ∞ Unit) → IO i ∞ Unit
sequenceIO [] .force = return' unit
sequenceIO (p ∷ l) = p >>= (λ _ → sequenceIO l)

Return : {i : Size} → {int : IOInterface} →  {A : Set} → A → IO int i A
Return a .force = return' a

Do : {i : Size} → {int : IOInterface} → (c : int .Command)
                → IO int i (int .Response c)
Do c .force = do' c Return

module _  {I : IOInterface }
          (let C = Command I)
          (let R = Response I)
           where
  mutual
    fmap : (i : Size) → {A B : Set} → (f : A → B)
            → IO I i A
            → IO I i B
    fmap i {A} {B} f p .force {j} = fmap' j {A} {B} f (p .force {j})

    fmap' : (i : Size) → {A B : Set} → (f : A → B )
            → IO' I i A
            → IO' I i B
    fmap' i {A} {B} f (do' c f₁) = do' c (λ r → fmap i {A} {B} f (f₁ r))
    fmap' i {A} {B} f (return' a) = return' (f a)

module _ (I : IOInterface )
         (let C = I .Command)
         (let R = I .Response)
           where

    data IOind (A : Set) : Set where

      do''     : (c : C) (f : (r : R c) → IOind A) → IOind A
      return'' : (a : A) → IOind A

_>>''_ : {I : IOInterface}(let C = I .Command)(let R = I .Response)
         {A B : Set} (p : IOind I A) (q : A → IOind I B) → IOind I B
do'' c f >>'' q = do'' c (λ r →  f r >>'' q)
return'' a >>'' q = q a

module _ {I : Interface }
         (let M = I .Method)
         (let R = I .Result)
           where

  translate : ∀{A : Set}
               → Object I
               → IOind (objectInterfToIOInterf I) A
               →  A × Object I
  translate {A} obj (do'' c p) = obj .objectMethod c ▹ λ {(x , o')
                                      → translate {A} o' (p x)  }
  translate {A} obj (return'' a) = a , obj


-- Data: init commit

--{-# OPTIONS --show-implicit #-}
--{-# OPTIONS --rewriting #-}
module Oscar.Data0 where

data ⟦⟧ : Set where
  ∅ : ⟦⟧
  ! : ⟦⟧ → ⟦⟧

data ⟦_⟧ {a} (A : Set a) : Set a where
  ∅ : ⟦ A ⟧
  _∷_ : A → ⟦ A ⟧ → ⟦ A ⟧

data ⟦⟧[_] : ⟦⟧ → Set where
  ∅ : ∀ {n} → ⟦⟧[ ! n ]
  ! : ∀ {n} → ⟦⟧[ n ] → ⟦⟧[ ! n ]

data ⟦_⟧[_] {a} (A : ⟦⟧ → Set a) : ⟦⟧ → Set a where
  ∅ : ∀ {n} → ⟦ A ⟧[ ! n ]
  _∷_ : ∀ {n} → A n → ⟦ A ⟧[ n ] → ⟦ A ⟧[ ! n ]

data ⟦⟧[_≤↓_] (m : ⟦⟧) : ⟦⟧ → Set where
  ∅ : ⟦⟧[ m ≤↓ m ]
  ! : ∀ {n} → ⟦⟧[ m ≤↓ n ] → ⟦⟧[ m ≤↓ ! n ]

data ⟦_⟧[_≤↓_] {a} (A : ⟦⟧ → Set a) (m : ⟦⟧) : ⟦⟧ → Set a where
  ∅ : ⟦ A ⟧[ m ≤↓ m ]
  _∷_ : ∀ {n} → A n → ⟦ A ⟧[ m ≤↓ n ] → ⟦ A ⟧[ m ≤↓ ! n ]

data ⟦⟧[_↑≤_] (m : ⟦⟧) : ⟦⟧ → Set where
  ∅ : ⟦⟧[ m ↑≤ m ]
  ! : ∀ {n} → ⟦⟧[ ! m ↑≤ n ] → ⟦⟧[ m ↑≤ n ]

data ⟦_⟧[_↑≤_] {a} (A : ⟦⟧ → Set a) (m : ⟦⟧) : ⟦⟧ → Set a where
  ∅ : ⟦ A ⟧[ m ↑≤ m ]
  _∷_ : ∀ {n} → A m → ⟦ A ⟧[ ! m ↑≤ n ] → ⟦ A ⟧[ m ↑≤ n ]

data ⟦⟧[_↓≤↓_] : ⟦⟧ → ⟦⟧ → Set where
  ∅ : ∀ {n} → ⟦⟧[ ∅ ↓≤↓ n ]
  ! : ∀ {m n} → ⟦⟧[ m ↓≤↓ n ] → ⟦⟧[ ! m ↓≤↓ ! n ]

data ⟦_⟧[_↓≤↓_] {a} (A : ⟦⟧ → ⟦⟧ → Set a) : ⟦⟧ → ⟦⟧ → Set a where
  ∅ : ∀ {n} → ⟦ A ⟧[ ∅ ↓≤↓ n ]
  ! : ∀ {m n} → A m n → ⟦ A ⟧[ m ↓≤↓ n ] → ⟦ A ⟧[ ! m ↓≤↓ ! n ]

-- open import Oscar.Data.Unit
-- open import Oscar.Level
-- open import Data.Empty

-- 𝕋 : ∀ {a} {A : Set a} → A → Set
-- 𝕋 = λ _ → ⊤

-- postulate
--   ℓ : Level
--   Term : Set ℓ

-- -- module _ where -- second constructor is recursive

-- --   -- Nat
-- --   data ⟦⟧ : Set where
-- --     ∅ : ⟦⟧
-- --     ! : ⟦⟧ → ⟦⟧

-- --   -- List
-- --   data ⟦_⟧ {a} (A : Set a) : Set a where
-- --     ∅ : ⟦ A ⟧
-- --     _∷_ : A → ⟦ A ⟧ → ⟦ A ⟧

-- --   -- ⋆⋆ m, size: m
-- --   -- [ 0 ] = nothing
-- --   -- [ 1 ] = ∅0
-- --   -- [ 4 ] = ∅3 or !2∅3 or !1!2∅3 or !0!1!2∅3
-- --   data ⟦⟧[_] : ⟦⟧ → Set where
-- --     ∅ : ∀ {n} → ⟦⟧[ ! n ]
-- --     ! : ∀ {n} → ⟦⟧[ n ] → ⟦⟧[ ! n ]

-- --   data ⟦_⟧[_] {a} (A : ⟦⟧ → Set a) : ⟦⟧ → Set a where
-- --     ∅ : ∀ {n} → ⟦ A ⟧[ ! n ]
-- --     _∷_ : ∀ {n} → A n → ⟦ A ⟧[ n ] → ⟦ A ⟧[ ! n ]

-- --   -- 0 : ∅ (only)
-- --   -- 1 : ∅ or ! ∅
-- --   -- 2 : ∅ or ! ∅
-- --   -- 5 : ∅ or !
-- --   -- size: m + 1
-- --   -- ⋆⋆'' 0 = ∅0
-- --   -- ⋆⋆'' 4 = ∅(m=4) or !3∅4 or !2!3∅4 or !1!2!3∅4 or !0!1!2!3∅4
-- --   data ⋆⋆'' (m : ⟦⟧) : Set where
-- --     ∅ : ⋆⋆'' m
-- --     ! : ⋆⋆'' (! m) → ⋆⋆'' m

-- --   -- ⋆⋆'' ⊂ ⋆⋆

-- --   -- m ≤ n == n - 1 ⋱ m
-- --   -- m ↙ n
-- --   -- size = n - m
-- --   -- AList
-- --   -- 4≤↓2 = nothing
-- --   -- 2≤↓4 = !23!22∅22
-- --   data ⟦⟧[_≤↓_] (m : ⟦⟧) : ⟦⟧ → Set where
-- --     ∅ : ⟦⟧[ m ≤↓ m ]
-- --     ! : ∀ {n} → ⟦⟧[ m ≤↓ n ] → ⟦⟧[ m ≤↓ ! n ]
-- --     -- A n

-- --   （_⋱_］ : ⟦⟧ → ⟦⟧ → Set
-- --   （ n ⋱ m ］ = ⟦⟧[ m ≤↓ n ]

-- --   data ⟦_⟧[_≤↓_] {a} (A : ⟦⟧ → Set a) (m : ⟦⟧) : ⟦⟧ → Set where
-- --     ∅ : ⟦ A ⟧[ m ≤↓ m ]
-- --     ! : ∀ {n} → A n → ⟦ A ⟧[ m ≤↓ n ] → ⟦⟧[ m ≤↓ ! n ]

-- --   -- m ≤ n = m ⋰ n - 1
-- --   -- m ↗ n
-- --   -- size = n - m (+1?)
-- --   -- 2↑≤4 = !24!34∅44
-- --   data _↑≤_ (m : ⟦⟧) : ⟦⟧ → Set where
-- --     ∅ : m ↑≤ m
-- --     ! : ∀ {n} → ! m ↑≤ n → m ↑≤ n
-- --     -- A m

-- --   ［_⋰_） : ⟦⟧ → ⟦⟧ → Set
-- --   ［ m ⋰ n ） = m ↑≤ n

-- --   -- m ≤ n == n - 1 ⋱ n - m && m - 1 ⋱ 0
-- --   -- size = m (+1?)
-- --   -- Inj
-- --   -- 2↓≤↓4 = !13!02∅02
-- --   data _↓≤↓_ : ⟦⟧ → ⟦⟧ → Set where
-- --     ∅ : ∀ {n} → ∅ ↓≤↓ n
-- --     ! : ∀ {m n} → m ↓≤↓ n → ! m ↓≤↓ ! n -- A m n

-- --   -- Fin
-- --   -- P 0 = ∅0 or !0∅1 or !0!1∅2 or ...
-- --   -- P 3 = ∅3 or !3∅4 or !3!4∅5 or ... (infinite)
-- --   data P (n : ⋆) : Set where
-- --     ∅ : P n
-- --     ! : P (! n) → P n

-- --   {-
-- --     3 <= 5 = ! (4 <= 5) = ! ! (5 <= 5) = ! ! ∅
-- --     3≤5 witnesses
-- --     n=3,m=5
-- --       4   5
-- --   -}
-- --   -- m ≤ n == m ... n - 1 (this is the same as the two-indexed version)
-- --   data _≤_ (n : ⋆) : ⋆ → Set where
-- --     ∅ : n ≤ n
-- --     ! : ∀ {m} → ! n ≤ m → n ≤ m
-- --   -- or
-- --   -- m ≤ n == n - 1 ... m

-- --   three : ⋆
-- --   three = ! (! (! ∅))

-- --   five : ⋆
-- --   five = ! (! three)

-- --   foo : three ≤ five
-- --   foo = ! {n = {!!}} (! {n = {!!}} ∅)

-- -- --   {-
-- -- --     3 <= 5 = 3 <= ! 4 = ! (3 <= 4) = ! (! (3 <= 3)) = ! ! ∅
-- -- --     3 ≤ 5 witnesses
-- -- --     n=3,m=4
-- -- --     n=3,m=3
-- -- --
-- -- --   -}

-- -- --   data _≤_ (n : ⋆) : ⋆ → Set where
-- -- --     ∅ : n ≤ n
-- -- --     ! : ∀ {m} → n ≤ m → n ≤ ! m -- A m

-- -- --   {-
-- -- --     3 <= 5
-- -- --     m=2,n=4
-- -- --     m=1,n=3
-- -- --     m=0,n=2
-- -- --   -}
-- -- --   data _≤_ : ⋆ → ⋆ → Set where
-- -- --     ∅ : ∀ {n} → ∅ ≤ n
-- -- --     ! : ∀ {m n} → m ≤ n → ! m ≤ ! n

-- -- -- --   data # (n : ⋆) : Set where
-- -- -- --     ∅ : # n
-- -- -- --     ! : # (

-- -- -- --   data # : ⋆ → Set where
-- -- -- --     ∅ : # n
-- -- -- --     ! : ⋆

-- -- -- --   data ⋆[_] {a} (A : Set a) : Set a where
-- -- -- --     ∅ : ⋆[ A ]
-- -- -- --     _∷_ : A → ⋆[ A ] → ⋆[ A ]

-- -- -- --   data _≥_ (n : ⋆) : ⋆ → Set where
-- -- -- --     ∅ : n ≥ n
-- -- -- --     ! : ∀ {m} → n ≥ ¹⁺ m → n ≥ m

-- -- -- -- {-
-- -- -- --   data _≤_ (n : ⋆) : ⋆ → Set where
-- -- -- --     ∅ : n ≤ n
-- -- -- --     ! : ∀ {m} → n ≤ m → n ≤ ¹⁺ m
-- -- -- -- -}
-- -- -- --   data _≥_ : ⋆ → ⋆ → Set where
-- -- -- --     ∅ : ∀ {n} → n ≥ ∅
-- -- -- --     ! : ∀ {m n} → n ≥ m → ¹⁺ m ≤ ¹⁺ n

-- -- -- --   _≱_ : ⋆ → ⋆ → Set
-- -- -- --   n ≱ m = n ≥ m → ⊥

-- -- -- --   ε : ∀ {m} → m ≥ m
-- -- -- --   ε = ≥∅

-- -- -- --   ¹⁺≥ : ∀ {n m} → n ≥ m → ¹⁺ n ≥ m
-- -- -- --   ¹⁺≥ ≥∅ = ≥⁻¹ ≥∅
-- -- -- --   ¹⁺≥ (≥⁻¹ n≥m) = ≥⁻¹ (¹⁺≥ n≥m)

-- -- -- --   ∅≱¹⁺ : ∀ {n} → ∅ ≱ ¹⁺ n
-- -- -- --   ∅≱¹⁺ (≥⁻¹ ∅≥²⁺n) = ∅≱¹⁺ ∅≥²⁺n

-- -- -- --   _∙_ : ∀ {n m} → n ≥ m → ∀ {l} → m ≥ l → n ≥ l
-- -- -- --   ≥∅ ∙ ≥∅ = ≥∅
-- -- -- --   ≥∅ ∙ ≥⁻¹ x₁ = ⊥-elim ({!∅≱¹⁺ !})
-- -- -- --   ≥⁻¹ x ∙ ≥∅ = {!!}
-- -- -- --   _∙_ {n} {m} (≥⁻¹ x) {l} (≥⁻¹ x₁) = ≥⁻¹ (x ∙ ¹⁺≥ x₁)

-- -- -- --   stop≥ : ∀ {n} → n ≱ ¹⁺ n
-- -- -- --   stop≥ {∅} (≥⁻¹ x) = ∅≱¹⁺ x
-- -- -- --   stop≥ {¹⁺ n} (≥⁻¹ (≥⁻¹ x)) = {!stop≥ x!}

-- -- -- --   ¹⁺≥¹⁺ : ∀ {n m} → n ≥ m → ¹⁺ n ≥ ¹⁺ m
-- -- -- --   ¹⁺≥¹⁺ {∅} ≥∅ = ≥⁻¹ {¹⁺ ∅} {!!}
-- -- -- --   ¹⁺≥¹⁺ {¹⁺ n} ≥∅ = {!!}
-- -- -- --   ¹⁺≥¹⁺ (≥⁻¹ x) = {!!}

-- -- -- --   ⁻¹≥⁻¹ : ∀ {n m} → ¹⁺ n ≥ ¹⁺ m → n ≥ m
-- -- -- --   ⁻¹≥⁻¹ {n} {∅} (≥⁻¹ x) = {!!}
-- -- -- --   ⁻¹≥⁻¹ {∅} {¹⁺ m} (≥⁻¹ x) = ⊥-elim (∅≱¹⁺ (⁻¹≥⁻¹ x))
-- -- -- --   ⁻¹≥⁻¹ {¹⁺ n} {¹⁺ m} (≥⁻¹ x) = (⁻¹≥⁻¹ x) ∙ ¹⁺≥ {!!}

-- -- -- -- --   1>=1 : ¹⁺ ∅ ≥ ¹⁺ ∅
-- -- -- -- --   1>=1 = ¹⁺ {!!}

-- -- -- -- --   {- ⋮↓ -}
-- -- -- -- --   {- h  ｛ A ∣ 7 ≥ 4 ｝ = ｛ A 7 4 , A 7 5 , A 7 6 , A 7 7 ｝ -}
-- -- -- -- --   {- g  ｛ A ∣ 4 ≥ 2 ｝ = ｛ A 4 2 , A 4 3 , A 4 4 ｝ -}
-- -- -- -- --   {- h∘g｛ A ∣ 7 ≥ 2 ｝ = ｛ A 7 2 , A 7 3 , A 7 4 , A 7 5 , A 7 6 , A 7 7 ｝ -}
-- -- -- -- --   {- f  ｛ A ∣ 2 ≥ 0 ｝ = ｛ ｝ -}
-- -- -- -- --   {- g∘f｛ A ∣ 4 ≥ 0 ｝ = ｛ A 4 0 , A 4 1 , A 4 2 , A 4 3 , A 4 4 ｝ -}
-- -- -- -- --   data ⋆[_/_≥_] {a} (A : ⋆ → ⋆ → Set a) (m : ⋆) : ⋆ → Set a where
-- -- -- -- --     ∅ : ⋆[ A / m ≥ ∅ ]
-- -- -- -- --     _∷_ : ∀ {n} → A m n → ⋆[ A / m ≥ ¹⁺ n ] → ⋆[ A / m ≥ n ]

-- -- -- -- --   _≥'_ : ⋆ → ⋆ → Set
-- -- -- -- --   m ≥' n = ⋆[ (λ _ _ → ⊤) / m ≥ n ]

-- -- -- -- --   data _≤_ : ⋆ → ⋆ → Set where
-- -- -- -- --     ∅ : ∀ {n} → ∅ ≤ n
-- -- -- -- --     ¹⁺_ : ∀ {m n} → m ≤ n → ¹⁺ m ≤ ¹⁺ n

-- -- -- -- --   {- ⃔⋱ -}
-- -- -- -- --   {- ｛ A ∣ 4 ≤ 7 ｝ = ｛ A 3 6 , A 2 5 , A 1 4 , A 0 3 ｝ -}
-- -- -- -- --   {- ｛ A ∣ 2 ≤ 4 ｝ = ｛ A 1 3 , A 0 2 ｝ -}
-- -- -- -- --   data ⋆[_/_≤_] {a} (A : ⋆ → ⋆ → Set a) : ⋆ → ⋆ → Set a where
-- -- -- -- --     ∅ : ∀ {n} → ⋆[ A / ∅ ≤ n ]
-- -- -- -- --     _∷_ : ∀ {m n} → A m n → ⋆[ A / m ≤ n ] → ⋆[ A / ¹⁺ m ≤ ¹⁺ n ]

-- -- -- -- -- --   ---- indices on first and second constructors: 1 and 2
-- -- -- -- -- --   data ⋆[_,_] : ⋆ → ⋆ → Set where
-- -- -- -- -- --     ∅ : ∀ {n} → ⋆[ n , n ]
-- -- -- -- -- --     ! : ∀ {m n} → ⋆[ m , n ] → ⋆[ m , ! n ]

-- -- -- -- -- --   data ⋆[_,_] : ⋆ → ⋆ → Set where
-- -- -- -- -- --     ∅ : ∀ {m n} → ⋆[ m , n ]
-- -- -- -- -- --     ! : ∀ {m n} → ⋆[ m , n ] → ⋆[ ! m , ! n ]

-- -- -- -- -- --   -- ?
-- -- -- -- -- --   data _≛_ : ⋆ → ⋆ → Set where
-- -- -- -- -- --     ∅ : ∅ ≛ ∅
-- -- -- -- -- --     ! : ∀ {m} → ⋆[ m , m ] → ⋆[ ! m , ! m ]

-- -- -- -- -- --   data [_/_↦_] {a} (A : ⋆ → ⋆ → Set a) : ⋆ → ⋆ → Set a where
-- -- -- -- -- --     ∅ : ∀ {n} → [ A / ∅ ↦ n ]
-- -- -- -- -- --     ! : ∀ {m n} → A m n → [ A / ! m ↦ ! n ]

-- -- -- -- -- -- module _ where -- Two constructors, where the second constructor adds a payload and a recursive element

-- -- -- -- -- -- -- List
-- -- -- -- -- -- data [_] {a} (A : Set a) : Set a where
-- -- -- -- -- --   ∅ : [ A ]
-- -- -- -- -- --   _,_ : A → [ A ] → [ A ]

-- -- -- -- -- -- -- Fin
-- -- -- -- -- -- ⋆[_] = ⋆[ ∅ ,_]

-- -- -- -- -- -- record ⊤ : Set where

-- -- -- -- -- -- record ∃ {a} {A : Set a} {b} (B : A → Set b) : Set (a ⊔ b) where
-- -- -- -- -- --   field
-- -- -- -- -- --     ⟱ : A
-- -- -- -- -- --     ⟰ : B ⟱

-- -- -- -- -- -- syntax ∃ (λ x → f) = ∃[ x ] f

-- -- -- -- -- -- _×_ : ∀ {a} (A : Set a) {b} (B : Set b) → Set (a ⊔ b)
-- -- -- -- -- -- A × B = ∃ {A = A} (λ _ → B)

-- -- -- -- -- -- --
-- -- -- -- -- -- [_↦_] : ⋆ → ⋆ → Set
-- -- -- -- -- -- [_↦_] = [ (λ m n → ⋆[ ! m ] × {![ m ↦ n ]!}) /_↦_]

-- -- -- -- --   -- open import Agda.Builtin.Equality
-- -- -- -- --   -- open import Data.Empty


module SyntaxRaw where

import Level
open import Data.Empty
open import Data.Unit as Unit
open import Data.Nat
open import Data.List as List renaming ([] to Ø; [_] to [_]L)
open import Data.List.Properties using (++-monoid)
open import NonEmptyList as NList
open import Data.Vec as Vec hiding ([_]; _++_)
open import Data.Product as Prod
open import Function

open import Relation.Binary.PropositionalEquality as PE hiding ([_])
open import Relation.Binary using (module IsEquivalence; Setoid; module Setoid)
open ≡-Reasoning

open import Common.Context as Context

open import Algebra
open Monoid {{ ... }} hiding (refl)

data Phantom {A : Set} (a : A) : Set where
  phantom : Phantom a

record Univ (P : Phantom tt) : Set where
  field
    x : ⊤

U : Set
U = Σ (Phantom tt) Univ

∗ : U
∗ = (phantom , record { x = tt })

length' : {A : Set} → List A → ℕ
length' Ø = 0
length' (x ∷ xs) = suc (length' xs)

length'-hom : {A : Set} → (l₁ l₂ : List A) →
             length' (l₁ ++ l₂) ≡ length' l₁ + length' l₂
length'-hom Ø        l₂ = refl
length'-hom (x ∷ l₁) l₂ = cong suc (length'-hom l₁ l₂)

length'ᵣ-1 : {A : Set} (l : List A) (a : A) →
             (length' l) + 1 ≡ length' (l ++ a ∷ Ø)
length'ᵣ-1 Ø a = refl
length'ᵣ-1 (x ∷ l) a = cong suc (length'ᵣ-1 l a)

length'-commute₁ : {A : Set} (l : List A) (a : A) →
                   length' (a ∷ l) ≡ length' (l ++ a ∷ Ø)
length'-commute₁ Ø a = refl
length'-commute₁ (x ∷ l) a = cong suc (length'-commute₁ l a)

mvVar : ∀ {A} (Γ₁ Γ₂ : List A) (x : A) → Γ₂ ++ x ∷ Γ₁ ≡ Γ₂ ↑ x ++ Γ₁
mvVar Γ₁ Ø x = refl
mvVar Γ₁ (y ∷ Γ₂) x = cong (λ u → y ∷ u) (mvVar Γ₁ Γ₂ x)

mvVar-length : ∀ {A} (Γ₁ Γ₂ : List A) (x : A) →
               length' (Γ₂ ++ x ∷ Γ₁) ≡ length' (Γ₂ ↑ x ++ Γ₁)
mvVar-length Γ₁ Γ₂ x = cong length' (mvVar Γ₁ Γ₂ x)

data FP : Set where
  μ : FP
  ν : FP

RawCtx : Set
RawCtx = Ctx U

instance ctx-monoid : Monoid _ _
ctx-monoid = ++-monoid U

RawVar : RawCtx → U → Set
RawVar = Var

TyCtx : Set
TyCtx = Ctx RawCtx

instance tyctx-monoid : Monoid _ _
tyctx-monoid = ++-monoid RawCtx

TyVar : TyCtx → RawCtx → Set
TyVar = Var

CtxMor : (TyCtx → RawCtx → RawCtx → Set) → RawCtx → RawCtx → Set
CtxMor R Γ₁ Γ₂ = Vec (R Ø Γ₁ Ø) (length' Γ₂)

FpData : (TyCtx → RawCtx → RawCtx → Set) → TyCtx → RawCtx → Set
FpData R Θ Γ = NList (Σ RawCtx (λ Γ' → CtxMor R Γ' Γ × R (Γ ∷ Θ) Γ' Ø))

-- | List of types, context morphisms and terms (Aₖ, fₖ, gₖ) such that
--            Γₖ, x : Aₖ[C/X] ⊢ gₖ : C fₖ or
--            Γₖ, x : C fₖ ⊢ gₖ : Aₖ[C/X],
-- which are the premisses of the rule for recursion and corecursion,
-- respectively.
FpMapData : (TyCtx → RawCtx → RawCtx → Set) → RawCtx → Set
FpMapData R Γ = NList (Σ RawCtx λ Γ' →
                         R [ Γ ]L Γ' Ø × CtxMor R Γ' Γ × R Ø (∗ ∷ Γ') Ø)

-- | Types and objects with their corresponding (untyped) type, object
-- variable contexts and parameter contexts.
-- Note that, if Θ | Γ₁ ⊢ M ⊸ Γ₂, i.e., M : Raw Θ Γ₁ Γ₂,
-- then Γ₂ needs to be read in reverse. The reason is that Γ₂ signifies
-- parameters that are instantiated in application-style. Also, variables
-- can be moved for types like in
-- Γ₁, x : A ⊢ B : Γ₂(∗)  → Γ₁ ⊢ λx.B : (x : A) ⊸ Γ₂(∗).
data Raw : TyCtx → RawCtx → RawCtx → Set where
  ----- Common constructors
  instRaw : {Θ : TyCtx} {Γ₁ Γ₂ : RawCtx} {A : U} →
            Raw Θ Γ₁ (Γ₂ ↑ A) → Raw Ø Γ₁ Ø → Raw Θ Γ₁ Γ₂

  ----- Object constructors
  unitRaw : (Γ : RawCtx) → Raw Ø Γ Ø
  objVarRaw : {Γ : RawCtx} {A : U} → RawVar Γ A → Raw Ø Γ Ø
  -- | initial/final dialgebra. dialgRaw ρ k is either αₖ or ξₖ, depending on ρ.
  dialgRaw : (Δ : RawCtx) (Γ : RawCtx) (A : U) → FP → ℕ → Raw Ø Δ (A ∷ Γ)
  recRaw : (Γ Δ : RawCtx) → FpMapData Raw Γ → FP → Raw Ø Δ (∗ ∷ Γ)

  ----- Type constructors
  ⊤-Raw : (Θ : TyCtx) (Γ : RawCtx) → Raw Θ Γ Ø
  tyVarRaw : {Θ : TyCtx} (Γ₁ : RawCtx) {Γ₂ : RawCtx} → TyVar Θ Γ₂ → Raw Θ Γ₁ Γ₂
  paramAbstrRaw : {Θ : TyCtx} {Γ₂ : RawCtx} (Γ₁ : RawCtx) {A : U} →
                  Raw Θ (A ∷ Γ₁) Γ₂ → Raw Θ Γ₁ (Γ₂ ↑ A)
  -- | Constructor for fixed points. The first component is intended to be
  -- the context morphism, the second is the type.
  fpRaw : {Θ : TyCtx} {Γ₂ : RawCtx} (Γ₁ : RawCtx) →
          FP → FpData Raw Θ Γ₂ → Raw Θ Γ₁ Γ₂

weakenObjVar : (Γ₁ : RawCtx) {Γ₂ : RawCtx} →
               (A : U) {B : U} → RawVar (Γ₁ ++ Γ₂) B → RawVar (Γ₁ ++ A ∷ Γ₂) B
weakenObjVar Ø         A x           = succ _ x
weakenObjVar (._ ∷ Γ₁) A zero        = zero
weakenObjVar (B ∷ Γ₁)  A (succ ._ x) = succ _ (weakenObjVar Γ₁ A x)

weaken : {Θ : TyCtx} (Γ₁ : RawCtx) {Γ₂ Γ₃ : RawCtx} →
         (A : U) → Raw Θ (Γ₁ ++ Γ₂) Γ₃ → Raw Θ (Γ₁ ++ A ∷ Γ₂) Γ₃
weaken Γ₁ {Γ₂} A (instRaw t s)                     =
  instRaw (weaken Γ₁ A t) (weaken Γ₁ A s)
weaken Γ₁ {Γ₂} A (unitRaw .(Γ₁ ++ Γ₂))             = unitRaw _
weaken Γ₁ {Γ₂} A (objVarRaw x)         =
  objVarRaw (weakenObjVar Γ₁ A x)
weaken Γ₁ {Γ₂} A (dialgRaw .(Γ₁ ++ Γ₂) Γ B ρ k)    = dialgRaw _ Γ B ρ k
weaken Γ₁ {Γ₂} A (recRaw Γ .(Γ₁ ++ Γ₂) gs ρ)       = recRaw Γ _ gs ρ
weaken Γ₁ {Γ₂} A (⊤-Raw Θ .(Γ₁ ++ Γ₂))             = ⊤-Raw Θ _
weaken Γ₁ {Γ₂} A (tyVarRaw .(Γ₁ ++ Γ₂) X)          = tyVarRaw _ X
weaken Γ₁ {Γ₂} A (paramAbstrRaw .(Γ₁ ++ Γ₂) {B} C) =
  paramAbstrRaw (Γ₁ ++ A ∷ Γ₂) (weaken (B ∷ Γ₁) A C)
weaken Γ₁ {Γ₂} A (fpRaw .(Γ₁ ++ Γ₂) ρ D)           = fpRaw _ ρ D

weaken₁ : ∀ {Θ Γ₁ Γ₂} → (A : U) → Raw Θ Γ₁ Γ₂ → Raw Θ (A ∷ Γ₁) Γ₂
weaken₁ = weaken Ø

ctxid : (Γ : RawCtx) → CtxMor Raw Γ Γ
ctxid Ø = []
ctxid (A ∷ Γ) = (objVarRaw {A ∷ Γ} {A} zero)
                ∷ Vec.map (weaken Ø A) (ctxid Γ)

-- | Build the instantiation "t f" of a raw term t by a context morphism f
instWCtxMor : {Θ : TyCtx} {Γ₁ Γ₂ Γ₃ : RawCtx} →
              Raw Θ Γ₁ (Γ₃ ++ Γ₂) → CtxMor Raw Γ₁ Γ₂ → Raw Θ Γ₁ Γ₃
instWCtxMor {Θ} {Γ₁} {Ø} {Γ₃} t [] = subst (Raw Θ Γ₁) (proj₂ identity Γ₃) t
instWCtxMor {Θ} {Γ₁} {x ∷ Γ₂} {Γ₃} t (s ∷ f) =
  instRaw (instWCtxMor (subst (Raw Θ Γ₁) (mvVar _ Γ₃ x) t) f) s

-- | Retrieve the term to be substituted for a variable from a context morphism
get : {R : TyCtx → RawCtx → RawCtx → Set} {Γ₁ Γ₂ : RawCtx} {A : U} →
      CtxMor R Γ₂ Γ₁ → RawVar Γ₁ A → R Ø Γ₂ Ø
get {R} {Ø}       []     ()
get {R} {_ ∷ Γ₁} (M ∷ f) zero        = M
get {R} {_ ∷ Γ₁} (M ∷ f) (succ ._ x) = get {R} f x

-- | Extends a context morphism to be the identity on a new variable
extend : {Γ₁ Γ₂ : RawCtx} →
         (A : U) → CtxMor Raw Γ₂ Γ₁ → CtxMor Raw (A ∷ Γ₂) (A ∷ Γ₁)
extend {Γ₁} {Γ₂} A f = (objVarRaw {A ∷ Γ₂} {A} zero) ∷ (Vec.map (weaken₁ A) f)

-- | Substitution on raw terms
substRaw : ∀ {Θ Γ₁ Γ Γ₂} → Raw Θ Γ₁ Γ → CtxMor Raw Γ₂ Γ₁ → Raw Θ Γ₂ Γ
substRaw (instRaw M N)         f = instRaw (substRaw M f) (substRaw N f)
substRaw (unitRaw Γ)           f = unitRaw _
substRaw (objVarRaw x)         f = get {Raw} f x
substRaw (dialgRaw Δ Γ A ρ k)  f = dialgRaw _ Γ A ρ k
substRaw (recRaw Γ Δ gs ρ)     f = recRaw Γ _ gs ρ
substRaw (⊤-Raw Θ Γ)           f = ⊤-Raw Θ _
substRaw (tyVarRaw Γ₁ X)       f = tyVarRaw _ X
substRaw (paramAbstrRaw Γ₁ A)  f = paramAbstrRaw _ (substRaw A (extend _ f))
substRaw (fpRaw Γ₁ ρ D)        f = fpRaw _ ρ D

-- | Context morphism that projects on arbitrary prefix of a context
ctxProjRaw : (Γ₁ Γ₂ : RawCtx) → CtxMor Raw (Γ₂ ++ Γ₁) Γ₁
ctxProjRaw Γ₁ Ø = ctxid Γ₁
ctxProjRaw Γ₁ (A ∷ Γ₂) = Vec.map (weaken₁ A) (ctxProjRaw Γ₁ Γ₂)

-- | Extend one step weakening to weakening by arbitrary contexts
weaken' : ∀ {Θ Γ₁ Γ₃} →
          (Γ₂ : RawCtx) → Raw Θ Γ₁ Γ₃ → Raw Θ (Γ₂ ++ Γ₁) Γ₃
weaken' {Γ₁ = Γ₁} Γ₂ t = substRaw t (ctxProjRaw Γ₁ Γ₂)

-----------------------------------------
--- Examples
-----------------------------------------

_︵_ : {A : Set} → A → A → List A
a ︵ b = a ∷ b ∷ Ø

-- | Binary product type
ProdRaw : (Γ : RawCtx) → Raw (Γ ︵ Γ) Ø Γ
ProdRaw Γ = fpRaw Ø ν D
  where
    Δ = Γ ︵ Γ

    A : TyVar (Γ ∷ Δ) Γ
    A = succ Γ zero

    B : TyVar (Γ ∷ Δ) Γ
    B = succ Γ (succ Γ zero)

    D₁ = (Γ , ctxid Γ , instWCtxMor (tyVarRaw Γ A) (ctxid Γ))

    D₂ = (Γ , ctxid Γ , instWCtxMor (tyVarRaw Γ B) (ctxid Γ))

    D : FpData Raw Δ Γ
    D = D₁ ∷ [ D₂ ]


{-# OPTIONS --rewriting #-}

module Luau.StrictMode where

open import Agda.Builtin.Equality using (_≡_)
open import FFI.Data.Maybe using (just; nothing)
open import Luau.Syntax using (Expr; Stat; Block; BinaryOperator; yes; nil; addr; var; binexp; var_∈_; _⟨_⟩∈_; function_is_end; _$_; block_is_end; local_←_; _∙_; done; return; name; +; -; *; /; <; >; <=; >=; ··)
open import Luau.Type using (Type; nil; number; string; boolean; _⇒_; _∪_; _∩_; src; tgt)
open import Luau.Subtyping using (_≮:_)
open import Luau.Heap using (Heap; function_is_end) renaming (_[_] to _[_]ᴴ)
open import Luau.VarCtxt using (VarCtxt; ∅; _⋒_; _↦_; _⊕_↦_; _⊝_) renaming (_[_] to _[_]ⱽ)
open import Luau.TypeCheck using (_⊢ᴮ_∈_; _⊢ᴱ_∈_; ⊢ᴴ_; ⊢ᴼ_; _⊢ᴴᴱ_▷_∈_; _⊢ᴴᴮ_▷_∈_; var; addr; app; binexp; block; return; local; function; srcBinOp)
open import Properties.Contradiction using (¬)
open import Properties.TypeCheck using (typeCheckᴮ)
open import Properties.Product using (_,_)

data Warningᴱ (H : Heap yes) {Γ} : ∀ {M T} → (Γ ⊢ᴱ M ∈ T) → Set
data Warningᴮ (H : Heap yes) {Γ} : ∀ {B T} → (Γ ⊢ᴮ B ∈ T) → Set

data Warningᴱ H {Γ} where

  UnallocatedAddress : ∀ {a T} →

    (H [ a ]ᴴ ≡ nothing) →
    ---------------------
    Warningᴱ H (addr {a} T)

  UnboundVariable : ∀ {x T p} →

    (Γ [ x ]ⱽ ≡ nothing) →
    ------------------------
    Warningᴱ H (var {x} {T} p)

  FunctionCallMismatch : ∀ {M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    (U ≮: src T) →
    -----------------
    Warningᴱ H (app D₁ D₂)

  app₁ : ∀ {M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    Warningᴱ H D₁ →
    -----------------
    Warningᴱ H (app D₁ D₂)

  app₂ : ∀ {M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    Warningᴱ H D₂ →
    -----------------
    Warningᴱ H (app D₁ D₂)

  BinOpMismatch₁ : ∀ {op M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    (T ≮: srcBinOp op) →
    ------------------------------
    Warningᴱ H (binexp {op} D₁ D₂)

  BinOpMismatch₂ : ∀ {op M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    (U ≮: srcBinOp op) →
    ------------------------------
    Warningᴱ H (binexp {op} D₁ D₂)

  bin₁ : ∀ {op M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    Warningᴱ H D₁ →
    ------------------------------
    Warningᴱ H (binexp {op} D₁ D₂)

  bin₂ : ∀ {op M N T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴱ N ∈ U} →

    Warningᴱ H D₂ →
    ------------------------------
    Warningᴱ H (binexp {op} D₁ D₂)

  FunctionDefnMismatch : ∀ {f x B T U V} {D : (Γ ⊕ x ↦ T) ⊢ᴮ B ∈ V} →

    (V ≮: U) →
    -------------------------
    Warningᴱ H (function {f} {U = U} D)

  function₁ : ∀ {f x B T U V} {D : (Γ ⊕ x ↦ T) ⊢ᴮ B ∈ V} →

    Warningᴮ H D →
    -------------------------
    Warningᴱ H (function {f} {U = U} D)

  BlockMismatch : ∀ {b B T U} {D : Γ ⊢ᴮ B ∈ U} →

    (U ≮: T) →
    ------------------------------
    Warningᴱ H (block {b} {T = T} D)

  block₁ : ∀ {b B T U} {D : Γ ⊢ᴮ B ∈ U} →

    Warningᴮ H D →
    ------------------------------
    Warningᴱ H (block {b} {T = T} D)

data Warningᴮ H {Γ} where

  return : ∀ {M B T U} {D₁ : Γ ⊢ᴱ M ∈ T} {D₂ : Γ ⊢ᴮ B ∈ U} →

    Warningᴱ H D₁ →
    ------------------
    Warningᴮ H (return D₁ D₂)

  LocalVarMismatch : ∀ {x M B T U V} {D₁ : Γ ⊢ᴱ M ∈ U} {D₂ : (Γ ⊕ x ↦ T) ⊢ᴮ B ∈ V} →

    (U ≮: T) →
    --------------------
    Warningᴮ H (local D₁ D₂)

  local₁ : ∀ {x M B T U V} {D₁ : Γ ⊢ᴱ M ∈ U} {D₂ : (Γ ⊕ x ↦ T) ⊢ᴮ B ∈ V} →

    Warningᴱ H D₁ →
    --------------------
    Warningᴮ H (local D₁ D₂)

  local₂ : ∀ {x M B T U V} {D₁ : Γ ⊢ᴱ M ∈ U} {D₂ : (Γ ⊕ x ↦ T) ⊢ᴮ B ∈ V} →

    Warningᴮ H D₂ →
    --------------------
    Warningᴮ H (local D₁ D₂)

  FunctionDefnMismatch : ∀ {f x B C T U V W} {D₁ : (Γ ⊕ x ↦ T) ⊢ᴮ C ∈ V} {D₂ : (Γ ⊕ f ↦ (T ⇒ U)) ⊢ᴮ B ∈ W} →

    (V ≮: U) →
    -------------------------------------
    Warningᴮ H (function D₁ D₂)

  function₁ : ∀ {f x B C T U V W} {D₁ : (Γ ⊕ x ↦ T) ⊢ᴮ C ∈ V} {D₂ : (Γ ⊕ f ↦ (T ⇒ U)) ⊢ᴮ B ∈ W} →

    Warningᴮ H D₁ →
    --------------------
    Warningᴮ H (function D₁ D₂)

  function₂ : ∀ {f x B C T U V W} {D₁ : (Γ ⊕ x ↦ T) ⊢ᴮ C ∈ V} {D₂ : (Γ ⊕ f ↦ (T ⇒ U)) ⊢ᴮ B ∈ W} →

    Warningᴮ H D₂ →
    --------------------
    Warningᴮ H (function D₁ D₂)

data Warningᴼ (H : Heap yes) : ∀ {V} → (⊢ᴼ V) → Set where

  FunctionDefnMismatch : ∀ {f x B T U V} {D : (x ↦ T) ⊢ᴮ B ∈ V} →

    (V ≮: U) →
    ---------------------------------
    Warningᴼ H (function {f} {U = U} D)

  function₁ : ∀ {f x B T U V} {D : (x ↦ T) ⊢ᴮ B ∈ V} →

    Warningᴮ H D →
    ---------------------------------
    Warningᴼ H (function {f} {U = U} D)

data Warningᴴ H (D : ⊢ᴴ H) : Set where

  addr : ∀ a {O} →

    (p : H [ a ]ᴴ ≡ O) →
    Warningᴼ H (D a p) →
    ---------------
    Warningᴴ H D

data Warningᴴᴱ H {Γ M T} : (Γ ⊢ᴴᴱ H ▷ M ∈ T) → Set where

  heap : ∀ {D₁ : ⊢ᴴ H} {D₂ : Γ ⊢ᴱ M ∈ T} →

    Warningᴴ H D₁ →
    -----------------
    Warningᴴᴱ H (D₁ , D₂)

  expr : ∀ {D₁ : ⊢ᴴ H} {D₂ : Γ ⊢ᴱ M ∈ T} →

    Warningᴱ H D₂ →
    ---------------------
    Warningᴴᴱ H (D₁ , D₂)

data Warningᴴᴮ H {Γ B T} : (Γ ⊢ᴴᴮ H ▷ B ∈ T) → Set where

  heap : ∀ {D₁ : ⊢ᴴ H} {D₂ : Γ ⊢ᴮ B ∈ T} →

    Warningᴴ H D₁ →
    -----------------
    Warningᴴᴮ H (D₁ , D₂)

  block : ∀ {D₁ : ⊢ᴴ H} {D₂ : Γ ⊢ᴮ B ∈ T} →

    Warningᴮ H D₂ →
    ---------------------
    Warningᴴᴮ H (D₁ , D₂)


-- The following deeply left-nested expression illustrates both a
-- problem in a previous implementation of the occurrence machinery,
-- and a problem in the one that is current at the time of writing.

F : Set → Set
F X = (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((X → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X)) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X) → X