~ubuntu-branches/ubuntu/maverick/agda-stdlib/maverick

« back to all changes in this revision

Viewing changes to src/Data/List/Any.agda

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2010-01-08 23:35:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100108233509-l6ejt9xji64xysfb
Import upstream version 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- Lists where at least one element satisfies a given property
 
3
------------------------------------------------------------------------
 
4
 
 
5
module Data.List.Any where
 
6
 
 
7
open import Data.Empty
 
8
open import Data.Fin
 
9
open import Data.Function
 
10
open import Data.List as List using (List; []; _∷_)
 
11
open import Data.Product as Prod using (∃; _×_; _,_)
 
12
open import Level
 
13
open import Relation.Nullary
 
14
import Relation.Nullary.Decidable as Dec
 
15
open import Relation.Unary using () renaming (_⊆_ to _⋐_)
 
16
open import Relation.Binary
 
17
import Relation.Binary.InducedPreorders as Ind
 
18
open import Relation.Binary.List.Pointwise as ListEq using ([]; _∷_)
 
19
open import Relation.Binary.PropositionalEquality as PropEq
 
20
  using (_≡_)
 
21
import Relation.Binary.Props.Preorder as PP
 
22
 
 
23
-- Any P xs means that at least one element in xs satisfies P.
 
24
 
 
25
data Any {A} (P : A → Set) : List A → Set where
 
26
  here  : ∀ {x xs} (px  : P x)      → Any P (x ∷ xs)
 
27
  there : ∀ {x xs} (pxs : Any P xs) → Any P (x ∷ xs)
 
28
 
 
29
-- Map.
 
30
 
 
31
map : ∀ {A} {P Q : A → Set} → P ⋐ Q → Any P ⋐ Any Q
 
32
map g (here px)   = here (g px)
 
33
map g (there pxs) = there (map g pxs)
 
34
 
 
35
-- If the head does not satisfy the predicate, then the tail will.
 
36
 
 
37
tail : ∀ {A x xs} {P : A → Set} → ¬ P x → Any P (x ∷ xs) → Any P xs
 
38
tail ¬px (here  px)  = ⊥-elim (¬px px)
 
39
tail ¬px (there pxs) = pxs
 
40
 
 
41
-- Decides Any.
 
42
 
 
43
any : ∀ {A} {P : A → Set} →
 
44
      (∀ x → Dec (P x)) → (xs : List A) → Dec (Any P xs)
 
45
any p []       = no λ()
 
46
any p (x ∷ xs) with p x
 
47
any p (x ∷ xs) | yes px = yes (here px)
 
48
any p (x ∷ xs) | no ¬px = Dec.map (there , tail ¬px) (any p xs)
 
49
 
 
50
-- index x∈xs is the list position (zero-based) which x∈xs points to.
 
51
 
 
52
index : ∀ {A} {P : A → Set} {xs} → Any P xs → Fin (List.length xs)
 
53
index (here  px)  = zero
 
54
index (there pxs) = suc (index pxs)
 
55
 
 
56
------------------------------------------------------------------------
 
57
-- List membership and some related definitions
 
58
 
 
59
module Membership (S : Setoid zero zero) where
 
60
 
 
61
  private
 
62
    open module  S = Setoid S using (_≈_) renaming (Carrier to A)
 
63
    open module LS = Setoid (ListEq.setoid S)
 
64
      using () renaming (_≈_ to _≋_)
 
65
 
 
66
  -- If a predicate P respects the underlying equality then Any P
 
67
  -- respects the list equality.
 
68
 
 
69
  lift-resp : ∀ {P} → P Respects _≈_ → Any P Respects _≋_
 
70
  lift-resp resp []            ()
 
71
  lift-resp resp (x≈y ∷ xs≈ys) (here px)   = here (resp x≈y px)
 
72
  lift-resp resp (x≈y ∷ xs≈ys) (there pxs) =
 
73
    there (lift-resp resp xs≈ys pxs)
 
74
 
 
75
  -- List membership.
 
76
 
 
77
  infix 4 _∈_ _∉_
 
78
 
 
79
  _∈_ : A → List A → Set
 
80
  x ∈ xs = Any (_≈_ x) xs
 
81
 
 
82
  _∉_ : A → List A → Set
 
83
  x ∉ xs = ¬ x ∈ xs
 
84
 
 
85
  -- Subsets.
 
86
 
 
87
  infix 4 _⊆_ _⊈_
 
88
 
 
89
  _⊆_ : List A → List A → Set
 
90
  xs ⊆ ys = ∀ {x} → x ∈ xs → x ∈ ys
 
91
 
 
92
  _⊈_ : List A → List A → Set
 
93
  xs ⊈ ys = ¬ xs ⊆ ys
 
94
 
 
95
  -- Equality is respected by the predicate which is used to define
 
96
  -- _∈_.
 
97
 
 
98
  ∈-resp-≈ : ∀ {x} → (_≈_ x) Respects _≈_
 
99
  ∈-resp-≈ = flip S.trans
 
100
 
 
101
  -- List equality is respected by _∈_.
 
102
 
 
103
  ∈-resp-list-≈ : ∀ {x} → _∈_ x Respects _≋_
 
104
  ∈-resp-list-≈ = lift-resp ∈-resp-≈
 
105
 
 
106
  -- _⊆_ is a preorder.
 
107
 
 
108
  ⊆-preorder : Preorder _ _ _
 
109
  ⊆-preorder = Ind.InducedPreorder₂ (ListEq.setoid S) _∈_ ∈-resp-list-≈
 
110
 
 
111
  module ⊆-Reasoning where
 
112
    import Relation.Binary.PreorderReasoning as PreR
 
113
    open PreR ⊆-preorder public
 
114
      renaming (_∼⟨_⟩_ to _⊆⟨_⟩_)
 
115
 
 
116
    infix 1 _∈⟨_⟩_
 
117
 
 
118
    _∈⟨_⟩_ : ∀ x {xs ys} → x ∈ xs → xs IsRelatedTo ys → x ∈ ys
 
119
    x ∈⟨ x∈xs ⟩ xs⊆ys = (begin xs⊆ys) x∈xs
 
120
 
 
121
  -- Set equality, i.e. an equality which ignores order and
 
122
  -- multiplicity.
 
123
 
 
124
  set-equality : Setoid _ _
 
125
  set-equality = PP.inducedEquivalence ⊆-preorder
 
126
 
 
127
  -- A variant of List.map.
 
128
 
 
129
  map-with-∈ : ∀ {B : Set} (xs : List A) → (∀ {x} → x ∈ xs → B) → List B
 
130
  map-with-∈ []       f = []
 
131
  map-with-∈ (x ∷ xs) f = f (here S.refl) ∷ map-with-∈ xs (f ∘ there)
 
132
 
 
133
  -- Finds an element satisfying the predicate.
 
134
 
 
135
  find : ∀ {P : A → Set} {xs} → Any P xs → ∃ λ x → x ∈ xs × P x
 
136
  find (here px)   = (_ , here S.refl , px)
 
137
  find (there pxs) = Prod.map id (Prod.map there id) (find pxs)
 
138
 
 
139
  lose : ∀ {P x xs} → P Respects _≈_ → x ∈ xs → P x → Any P xs
 
140
  lose resp x∈xs px = map (flip resp px) x∈xs
 
141
 
 
142
-- The code above instantiated (and slightly changed) for
 
143
-- propositional equality.
 
144
 
 
145
module Membership-≡ {A : Set} where
 
146
 
 
147
  private
 
148
    open module M = Membership (PropEq.setoid A) public
 
149
      hiding ( lift-resp; lose
 
150
             ; ⊆-preorder; module ⊆-Reasoning; set-equality
 
151
             )
 
152
 
 
153
  lose : ∀ {P x xs} → x ∈ xs → P x → Any P xs
 
154
  lose {P} = M.lose (PropEq.subst P)
 
155
 
 
156
  -- _⊆_ is a preorder.
 
157
 
 
158
  ⊆-preorder : Preorder _ _ _
 
159
  ⊆-preorder = Ind.InducedPreorder₂ (PropEq.setoid (List A)) _∈_
 
160
                                    (PropEq.subst (_∈_ _))
 
161
 
 
162
  module ⊆-Reasoning where
 
163
    import Relation.Binary.PreorderReasoning as PreR
 
164
    open PreR ⊆-preorder public
 
165
      renaming (_∼⟨_⟩_ to _⊆⟨_⟩_; _≈⟨_⟩_ to _≡⟨_⟩_)
 
166
 
 
167
    infix 1 _∈⟨_⟩_
 
168
 
 
169
    _∈⟨_⟩_ : ∀ x {xs ys} → x ∈ xs → xs IsRelatedTo ys → x ∈ ys
 
170
    x ∈⟨ x∈xs ⟩ xs⊆ys = (begin xs⊆ys) x∈xs
 
171
 
 
172
  -- Set equality, i.e. an equality which ignores order and
 
173
  -- multiplicity.
 
174
 
 
175
  set-equality : Setoid _ _
 
176
  set-equality = PP.inducedEquivalence ⊆-preorder
 
177
 
 
178
------------------------------------------------------------------------
 
179
-- Another function
 
180
 
 
181
-- If any element satisfies P, then P is satisfied.
 
182
 
 
183
satisfied : ∀ {A} {P : A → Set} {xs} → Any P xs → ∃ P
 
184
satisfied = Prod.map id Prod.proj₂ ∘ Membership-≡.find