~ubuntu-branches/ubuntu/utopic/agda-stdlib/utopic-proposed

« back to all changes in this revision

Viewing changes to src/Data/Colist/Infinite-merge.agda

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-08-05 09:46:46 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140805094646-zqd0c4m8ndngqg6x
Tags: 0.8-1
* [4ca6fd0] Update debian/watch to fetch tarballs from github
* [84d4313] Imported Upstream version 0.8
* [7b08243] debian/control: Require agda 2.4.x per upstream
* [37e7e10] debian/control: Standards-Version → 3.9.5, no changes required.
* [9051b9d] Run upstream's "GenerateEverything" script

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- The Agda standard library
 
3
--
 
4
-- Infinite merge operation for coinductive lists
 
5
------------------------------------------------------------------------
 
6
 
 
7
module Data.Colist.Infinite-merge where
 
8
 
 
9
open import Coinduction
 
10
open import Data.Colist as Colist hiding (_⋎_)
 
11
open import Data.Nat
 
12
open import Data.Nat.Properties
 
13
open import Data.Product as Prod
 
14
open import Data.Sum
 
15
open import Function
 
16
open import Function.Equality using (_⟨$⟩_)
 
17
open import Function.Inverse as Inv using (_↔_; module Inverse)
 
18
import Function.Related as Related
 
19
open import Function.Related.TypeIsomorphisms
 
20
open import Induction.Nat
 
21
import Induction.WellFounded as WF
 
22
open import Relation.Binary.PropositionalEquality as P using (_≡_)
 
23
open import Relation.Binary.Sum
 
24
 
 
25
-- Some code that is used to work around Agda's syntactic guardedness
 
26
-- checker.
 
27
 
 
28
private
 
29
 
 
30
  infixr 5 _∷_ _⋎_
 
31
 
 
32
  data ColistP {a} (A : Set a) : Set a where
 
33
    []  : ColistP A
 
34
    _∷_ : A → ∞ (ColistP A) → ColistP A
 
35
    _⋎_ : ColistP A → ColistP A → ColistP A
 
36
 
 
37
  data ColistW {a} (A : Set a) : Set a where
 
38
    []  : ColistW A
 
39
    _∷_ : A → ColistP A → ColistW A
 
40
 
 
41
  program : ∀ {a} {A : Set a} → Colist A → ColistP A
 
42
  program []       = []
 
43
  program (x ∷ xs) = x ∷ ♯ program (♭ xs)
 
44
 
 
45
  mutual
 
46
 
 
47
    _⋎W_ : ∀ {a} {A : Set a} → ColistW A → ColistP A → ColistW A
 
48
    []       ⋎W ys = whnf ys
 
49
    (x ∷ xs) ⋎W ys = x ∷ (ys ⋎ xs)
 
50
 
 
51
    whnf : ∀ {a} {A : Set a} → ColistP A → ColistW A
 
52
    whnf []        = []
 
53
    whnf (x ∷ xs)  = x ∷ ♭ xs
 
54
    whnf (xs ⋎ ys) = whnf xs ⋎W ys
 
55
 
 
56
  mutual
 
57
 
 
58
    ⟦_⟧P : ∀ {a} {A : Set a} → ColistP A → Colist A
 
59
    ⟦ xs ⟧P = ⟦ whnf xs ⟧W
 
60
 
 
61
    ⟦_⟧W : ∀ {a} {A : Set a} → ColistW A → Colist A
 
62
    ⟦ [] ⟧W     = []
 
63
    ⟦ x ∷ xs ⟧W = x ∷ ♯ ⟦ xs ⟧P
 
64
 
 
65
  mutual
 
66
 
 
67
    ⋎-homP : ∀ {a} {A : Set a} (xs : ColistP A) {ys} →
 
68
             ⟦ xs ⋎ ys ⟧P ≈ ⟦ xs ⟧P Colist.⋎ ⟦ ys ⟧P
 
69
    ⋎-homP xs = ⋎-homW (whnf xs) _
 
70
 
 
71
    ⋎-homW : ∀ {a} {A : Set a} (xs : ColistW A) ys →
 
72
             ⟦ xs ⋎W ys ⟧W ≈ ⟦ xs ⟧W Colist.⋎ ⟦ ys ⟧P
 
73
    ⋎-homW (x ∷ xs) ys = x ∷ ♯ ⋎-homP ys
 
74
    ⋎-homW []       ys = begin ⟦ ys ⟧P ∎
 
75
      where open ≈-Reasoning
 
76
 
 
77
  ⟦program⟧P : ∀ {a} {A : Set a} (xs : Colist A) →
 
78
               ⟦ program xs ⟧P ≈ xs
 
79
  ⟦program⟧P []       = []
 
80
  ⟦program⟧P (x ∷ xs) = x ∷ ♯ ⟦program⟧P (♭ xs)
 
81
 
 
82
  Any-⋎P : ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} →
 
83
           Any P ⟦ program xs ⋎ ys ⟧P ↔ (Any P xs ⊎ Any P ⟦ ys ⟧P)
 
84
  Any-⋎P {P = P} xs {ys} =
 
85
    Any P ⟦ program xs ⋎ ys ⟧P                ↔⟨ Any-cong Inv.id (⋎-homP (program xs)) ⟩
 
86
    Any P (⟦ program xs ⟧P Colist.⋎ ⟦ ys ⟧P)  ↔⟨ Any-⋎ _ ⟩
 
87
    (Any P ⟦ program xs ⟧P ⊎ Any P ⟦ ys ⟧P)   ↔⟨ Any-cong Inv.id (⟦program⟧P _) ⊎-cong (_ ∎) ⟩
 
88
    (Any P xs ⊎ Any P ⟦ ys ⟧P)                ∎
 
89
    where open Related.EquationalReasoning
 
90
 
 
91
  index-Any-⋎P :
 
92
    ∀ {a p} {A : Set a} {P : A → Set p} xs {ys}
 
93
    (p : Any P ⟦ program xs ⋎ ys ⟧P) →
 
94
    index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎P xs) ⟨$⟩ p)
 
95
  index-Any-⋎P xs p
 
96
    with       Any-resp      id  (⋎-homW (whnf (program xs)) _) p
 
97
       | index-Any-resp {f = id} (⋎-homW (whnf (program xs)) _) p
 
98
  index-Any-⋎P xs p | q | q≡p
 
99
    with Inverse.to (Any-⋎ ⟦ program xs ⟧P) ⟨$⟩ q
 
100
       |       index-Any-⋎ ⟦ program xs ⟧P      q
 
101
  index-Any-⋎P xs p | q | q≡p | inj₂ r | r≤q rewrite q≡p = r≤q
 
102
  index-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q
 
103
    with       Any-resp      id  (⟦program⟧P xs) r
 
104
       | index-Any-resp {f = id} (⟦program⟧P xs) r
 
105
  index-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q | s | s≡r
 
106
    rewrite s≡r | q≡p = r≤q
 
107
 
 
108
-- Infinite variant of _⋎_.
 
109
 
 
110
private
 
111
 
 
112
  merge′ : ∀ {a} {A : Set a} → Colist (A × Colist A) → ColistP A
 
113
  merge′ []               = []
 
114
  merge′ ((x , xs) ∷ xss) = x ∷ ♯ (program xs ⋎ merge′ (♭ xss))
 
115
 
 
116
merge : ∀ {a} {A : Set a} → Colist (A × Colist A) → Colist A
 
117
merge xss = ⟦ merge′ xss ⟧P
 
118
 
 
119
-- Any lemma for merge.
 
120
 
 
121
Any-merge :
 
122
  ∀ {a p} {A : Set a} {P : A → Set p} xss →
 
123
  Any P (merge xss) ↔ Any (λ { (x , xs) → P x ⊎ Any P xs }) xss
 
124
Any-merge {P = P} = λ xss → record
 
125
  { to         = P.→-to-⟶ (proj₁ ∘ to xss)
 
126
  ; from       = P.→-to-⟶ from
 
127
  ; inverse-of = record
 
128
    { left-inverse-of  = proj₂ ∘ to xss
 
129
    ; right-inverse-of = λ p → begin
 
130
        proj₁ (to xss (from p))  ≡⟨ from-injective _ _ (proj₂ (to xss (from p))) ⟩
 
131
        p                        ∎
 
132
    }
 
133
  }
 
134
  where
 
135
  open P.≡-Reasoning
 
136
 
 
137
  -- The from function.
 
138
 
 
139
  Q = λ { (x , xs) → P x ⊎ Any P xs }
 
140
 
 
141
  from : ∀ {xss} → Any Q xss → Any P (merge xss)
 
142
  from (here (inj₁ p))        = here p
 
143
  from (here (inj₂ p))        = there (Inverse.from (Any-⋎P _)  ⟨$⟩ inj₁ p)
 
144
  from (there {x = _ , xs} p) = there (Inverse.from (Any-⋎P xs) ⟨$⟩ inj₂ (from p))
 
145
 
 
146
  -- Some lemmas.
 
147
 
 
148
  drop-there :
 
149
    ∀ {a p} {A : Set a} {P : A → Set p} {x xs} {p q : Any P _} →
 
150
    _≡_ {A = Any P (x ∷ xs)} (there p) (there q) → p ≡ q
 
151
  drop-there P.refl = P.refl
 
152
 
 
153
  drop-inj₁ : ∀ {a b} {A : Set a} {B : Set b} {x y} →
 
154
              _≡_ {A = A ⊎ B} (inj₁ x) (inj₁ y) → x ≡ y
 
155
  drop-inj₁ P.refl = P.refl
 
156
 
 
157
  drop-inj₂ : ∀ {a b} {A : Set a} {B : Set b} {x y} →
 
158
              _≡_ {A = A ⊎ B} (inj₂ x) (inj₂ y) → x ≡ y
 
159
  drop-inj₂ P.refl = P.refl
 
160
 
 
161
  -- The from function is injective.
 
162
 
 
163
  from-injective : ∀ {xss} (p₁ p₂ : Any Q xss) →
 
164
                   from p₁ ≡ from p₂ → p₁ ≡ p₂
 
165
  from-injective (here (inj₁ p))  (here (inj₁ .p)) P.refl = P.refl
 
166
  from-injective (here (inj₁ _))  (here (inj₂ _))  ()
 
167
  from-injective (here (inj₂ _))  (here (inj₁ _))  ()
 
168
  from-injective (here (inj₂ p₁)) (here (inj₂ p₂)) eq     =
 
169
    P.cong (here ∘ inj₂) $
 
170
    drop-inj₁ $
 
171
    Inverse.injective (Inv.sym (Any-⋎P _)) {x = inj₁ p₁} {y = inj₁ p₂} $
 
172
    drop-there eq
 
173
  from-injective (here (inj₁ _))  (there _)  ()
 
174
  from-injective (here (inj₂ p₁)) (there p₂) eq
 
175
    with Inverse.injective (Inv.sym (Any-⋎P _))
 
176
                           {x = inj₁ p₁} {y = inj₂ (from p₂)}
 
177
                           (drop-there eq)
 
178
  ... | ()
 
179
  from-injective (there _)  (here (inj₁ _))  ()
 
180
  from-injective (there p₁) (here (inj₂ p₂)) eq
 
181
    with Inverse.injective (Inv.sym (Any-⋎P _))
 
182
                           {x = inj₂ (from p₁)} {y = inj₁ p₂}
 
183
                           (drop-there eq)
 
184
  ... | ()
 
185
  from-injective (there {x = _ , xs} p₁) (there p₂) eq =
 
186
    P.cong there $
 
187
    from-injective p₁ p₂ $
 
188
    drop-inj₂ $
 
189
    Inverse.injective (Inv.sym (Any-⋎P xs))
 
190
                      {x = inj₂ (from p₁)} {y = inj₂ (from p₂)} $
 
191
    drop-there eq
 
192
 
 
193
  -- The to function (defined as a right inverse of from).
 
194
 
 
195
  Input = ∃ λ xss → Any P (merge xss)
 
196
 
 
197
  Pred : Input → Set _
 
198
  Pred (xss , p) = ∃ λ (q : Any Q xss) → from q ≡ p
 
199
 
 
200
  to : ∀ xss p → Pred (xss , p)
 
201
  to = λ xss p →
 
202
    WF.All.wfRec (WF.Inverse-image.well-founded size <-well-founded) _
 
203
                 Pred step (xss , p)
 
204
    where
 
205
    size : Input → ℕ
 
206
    size (_ , p) = index p
 
207
 
 
208
    step : ∀ p → WF.WfRec (_<′_ on size) Pred p → Pred p
 
209
    step ([]             , ())      rec
 
210
    step ((x , xs) ∷ xss , here  p) rec = here (inj₁ p) , P.refl
 
211
    step ((x , xs) ∷ xss , there p) rec
 
212
      with Inverse.to (Any-⋎P xs) ⟨$⟩ p
 
213
         | Inverse.left-inverse-of (Any-⋎P xs) p
 
214
         | index-Any-⋎P xs p
 
215
    step ((x , xs) ∷ xss , there .(Inverse.from (Any-⋎P xs) ⟨$⟩ inj₁ q)) rec | inj₁ q | P.refl | _   = here (inj₂ q) , P.refl
 
216
    step ((x , xs) ∷ xss , there .(Inverse.from (Any-⋎P xs) ⟨$⟩ inj₂ q)) rec | inj₂ q | P.refl | q≤p =
 
217
      Prod.map there
 
218
               (P.cong (there ∘ _⟨$⟩_ (Inverse.from (Any-⋎P xs)) ∘ inj₂))
 
219
               (rec (♭ xss , q) (s≤′s q≤p))
 
220
 
 
221
-- Every member of xss is a member of merge xss, and vice versa (with
 
222
-- equal multiplicities).
 
223
 
 
224
∈-merge : ∀ {a} {A : Set a} {y : A} xss →
 
225
          y ∈ merge xss ↔ ∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)
 
226
∈-merge {y = y} xss =
 
227
  y ∈ merge xss                                           ↔⟨ Any-merge _ ⟩
 
228
  Any (λ { (x , xs) → y ≡ x ⊎ y ∈ xs }) xss               ↔⟨ Any-∈ ⟩
 
229
  (∃ λ { (x , xs) → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs) })  ↔⟨ Σ-assoc ⟩
 
230
  (∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs))         ∎
 
231
  where open Related.EquationalReasoning