-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathListUtil.agda
160 lines (131 loc) · 6.22 KB
/
ListUtil.agda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
{-# OPTIONS --prop --rewriting #-}
module ListUtil where
infixr 5 _∷_
data List : (T : Set₀) → Set where
[] : {T : Set₀} → List T
_∷_ : {T : Set₀} → T → List T → List T
{-# BUILTIN LIST List #-}
private
variable
T : Set₀
L : List T
L' : List T
L'' : List T
A : T
B : T
-- Definition of list appartenance
-- The definition uses reflexivity and never any kind of equality
infix 3 _∈_
data _∈_ : T → List T → Prop where
zero∈ : A ∈ A ∷ L
next∈ : A ∈ L → A ∈ B ∷ L
{- RELATIONS BETWEEN LISTS -}
-- We have the following relations
-- ↗ ⊂⁰ ↘
-- ⊆ → ⊂ → ⊂⁺ → ∈*
infix 4 _⊆_ _⊂_ _⊂⁺_ _⊂⁰_ _∈*_
{- ⊆ : We can remove elements but only from the head of the list -}
-- Similar definition : {L L' : List T} → L ⊆ L' ++ L
data _⊆_ : List T → List T → Prop where
zero⊆ : L ⊆ L
next⊆ : L ⊆ L' → L ⊆ (A ∷ L')
-- One useful lemma
retro⊆ : {L L' : List T} → {A : T} → (A ∷ L) ⊆ L' → L ⊆ L'
retro⊆ {L' = []} () -- Impossible to have «A∷L ⊆ []»
retro⊆ {L' = B ∷ L'} zero⊆ = next⊆ zero⊆
retro⊆ {L' = B ∷ L'} (next⊆ h) = next⊆ (retro⊆ h)
refl⊆ : L ⊆ L
refl⊆ = zero⊆
tran⊆ : L ⊆ L' → L' ⊆ L'' → L ⊆ L''
tran⊆ zero⊆ h2 = h2
tran⊆ (next⊆ h1) h2 = tran⊆ h1 (retro⊆ h2)
{- ⊂ : We can remove elements anywhere on the list, no duplicates, no reordering -}
data _⊂_ : List T → List T → Prop where
zero⊂ : [] ⊂ L
both⊂ : L ⊂ L' → (A ∷ L) ⊂ (A ∷ L')
next⊂ : L ⊂ L' → L ⊂ (A ∷ L')
⊆→⊂ : L ⊆ L' → L ⊂ L'
refl⊂ : L ⊂ L
⊆→⊂ {L = []} h = zero⊂
⊆→⊂ {L = x ∷ L} zero⊆ = both⊂ (refl⊂)
⊆→⊂ {L = x ∷ L} (next⊆ h) = next⊂ (⊆→⊂ h)
refl⊂ = ⊆→⊂ refl⊆
tran⊂ : L ⊂ L' → L' ⊂ L'' → L ⊂ L''
tran⊂ zero⊂ h2 = zero⊂
tran⊂ (both⊂ h1) (both⊂ h2) = both⊂ (tran⊂ h1 h2)
tran⊂ (both⊂ h1) (next⊂ h2) = next⊂ (tran⊂ (both⊂ h1) h2)
tran⊂ (next⊂ h1) (both⊂ h2) = next⊂ (tran⊂ h1 h2)
tran⊂ (next⊂ h1) (next⊂ h2) = next⊂ (tran⊂ (next⊂ h1) h2)
{- ⊂⁰ : We can remove elements and reorder the list, as long as we don't duplicate the elements -}
-----> We do not have unicity of derivation ([A,A] ⊂⁰ [A,A] can be prove by identity or by swapping its two elements
--> We could do with some counting function, but ... it would not be nice, would it ?
data _⊂⁰_ : List T → List T → Prop where
zero⊂⁰ : _⊂⁰_ {T} [] []
next⊂⁰ : L ⊂⁰ L' → L ⊂⁰ A ∷ L'
both⊂⁰ : L ⊂⁰ L' → A ∷ L ⊂⁰ A ∷ L'
swap⊂⁰ : L ⊂⁰ A ∷ B ∷ L' → L ⊂⁰ B ∷ A ∷ L'
error : L ⊂⁰ L'
-- TODOTODOTODOTODO Fix this definition
{- ⊂⁺ : We can remove and duplicate elements, as long as we don't change the order -}
data _⊂⁺_ : List T → List T → Prop where
zero⊂⁺ : _⊂⁺_ {T} [] []
next⊂⁺ : L ⊂⁺ L' → L ⊂⁺ A ∷ L'
dup⊂⁺ : L ⊂⁺ A ∷ L' → A ∷ L ⊂⁺ A ∷ L'
⊂→⊂⁺ : L ⊂ L' → L ⊂⁺ L'
⊂→⊂⁺ {L' = []} zero⊂ = zero⊂⁺
⊂→⊂⁺ {L' = x ∷ L'} zero⊂ = next⊂⁺ (⊂→⊂⁺ zero⊂)
⊂→⊂⁺ (both⊂ h) = dup⊂⁺ (next⊂⁺ (⊂→⊂⁺ h))
⊂→⊂⁺ (next⊂ h) = next⊂⁺ (⊂→⊂⁺ h)
refl⊂⁺ : L ⊂⁺ L
refl⊂⁺ = ⊂→⊂⁺ refl⊂
tran⊂⁺ : L ⊂⁺ L' → L' ⊂⁺ L'' → L ⊂⁺ L''
tran⊂⁺ zero⊂⁺ zero⊂⁺ = zero⊂⁺
tran⊂⁺ zero⊂⁺ (next⊂⁺ h2) = next⊂⁺ h2
tran⊂⁺ (next⊂⁺ h1) (next⊂⁺ h2) = next⊂⁺ (tran⊂⁺ (next⊂⁺ h1) h2)
tran⊂⁺ (next⊂⁺ h1) (dup⊂⁺ h2) = tran⊂⁺ h1 h2
tran⊂⁺ (dup⊂⁺ h1) (next⊂⁺ h2) = next⊂⁺ (tran⊂⁺ (dup⊂⁺ h1) h2)
tran⊂⁺ (dup⊂⁺ h1) (dup⊂⁺ h2) = dup⊂⁺ (tran⊂⁺ h1 (dup⊂⁺ h2))
retro⊂⁺ : A ∷ L ⊂⁺ L' → L ⊂⁺ L'
retro⊂⁺ (next⊂⁺ h) = next⊂⁺ (retro⊂⁺ h)
retro⊂⁺ (dup⊂⁺ h) = h
{- ∈* : We can remove or duplicate elements and we can change their order -}
-- The weakest of all relations on lists
-- L ∈* L' if all elements of L exists in L' (no consideration for order nor duplication)
data _∈*_ : List T → List T → Prop where
zero∈* : [] ∈* L
next∈* : A ∈ L → L' ∈* L → (A ∷ L') ∈* L
-- Founding principle
mon∈∈* : A ∈ L → L ∈* L' → A ∈ L'
mon∈∈* zero∈ (next∈* x hl) = x
mon∈∈* (next∈ ha) (next∈* x hl) = mon∈∈* ha hl
-- We show that the relation is reflexive and is implied by ⊆
refl∈* : L ∈* L
⊂⁺→∈* : L ⊂⁺ L' → L ∈* L'
refl∈* {L = []} = zero∈*
refl∈* {L = x ∷ L} = next∈* zero∈ (⊂⁺→∈* (next⊂⁺ refl⊂⁺))
⊂⁺→∈* zero⊂⁺ = refl∈*
⊂⁺→∈* {L = []} (next⊂⁺ h) = zero∈*
⊂⁺→∈* {L = x ∷ L} (next⊂⁺ h) = next∈* (next∈ (mon∈∈* zero∈ (⊂⁺→∈* h))) (⊂⁺→∈* (retro⊂⁺ (next⊂⁺ h)))
⊂⁺→∈* (dup⊂⁺ h) = next∈* zero∈ (⊂⁺→∈* h)
-- Allows to grow ∈* to the right
right∈* : L ∈* L' → L ∈* (A ∷ L')
right∈* zero∈* = zero∈*
right∈* (next∈* x h) = next∈* (next∈ x) (right∈* h)
both∈* : L ∈* L' → (A ∷ L) ∈* (A ∷ L')
both∈* zero∈* = next∈* zero∈ zero∈*
both∈* (next∈* x h) = next∈* zero∈ (next∈* (next∈ x) (right∈* h))
tran∈* : L ∈* L' → L' ∈* L'' → L ∈* L''
tran∈* {L = []} = λ x x₁ → zero∈*
tran∈* {L = x ∷ L} (next∈* x₁ h1) h2 = next∈* (mon∈∈* x₁ h2) (tran∈* h1 h2)
⊆→∈* : L ⊆ L' → L ∈* L'
⊆→∈* h = ⊂⁺→∈* (⊂→⊂⁺ (⊆→⊂ h))
open import PropUtil using (Nat; zero; succ)
open import Agda.Primitive
variable
ℓ : Level
data Array (T : Set ℓ) : Nat → Set ℓ where
zero : Array T zero
next : {n : Nat} → T → Array T n → Array T (succ n)
map : {T U : Set ℓ} → (T → U) → {n : Nat} → Array T n → Array U n
map f zero = zero
map f (next t a) = next (f t) (map f a)