-
Notifications
You must be signed in to change notification settings - Fork 0
/
example_project.agda
226 lines (183 loc) · 9.15 KB
/
example_project.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
module example_project where
-- W tym projekcie formalizujemy prosty język zdefiniowany w
-- https://groups.seas.harvard.edu/courses/cs152/2019sp/lectures/lec02-smallstep.pdf
-- wraz z jego semantyką small-step.
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
open import Data.String.Base using (String)
open import Data.Nat.Base using (ℕ; _+_; _*_)
open import Data.Maybe using (Maybe; nothing; just)
open import Data.Product using (_×_; proj₁; proj₂) renaming (_,_ to ⟨_,_⟩)
open import Relation.Nullary using (¬_)
-- wprowadzamy type alias Var
Var : Set
Var = ℕ
-- Definiujemy składnię naszego języka.
-- W klasycznym zapisie BNF, wyrażenia naszego języka definiujemy:
-- e := var x | int n | x ≔ n ⨾ e | e ⊕ e | e ⊗ e
-- Używając ADT, definicja typu reprezentującego wyrażenia naszego języka jest
-- następująca:
data Exp : Set where
var : Var → Exp
int : ℕ → Exp
_≔_⨾_ : Var → Exp → Exp → Exp
_⊗_ : Exp → Exp → Exp
_⊕_ : Exp → Exp → Exp
-- na potrzeby przykładów wprowadzmy nazwe zmiennej (u nas zmienne są liczbami)
foo = 1
bar = 2
-- i zdefiniujmy przykładowe wyrażenie typu Exp:
example₁ : Exp
example₁ = foo ≔ ( int 6 ) ⨾ (((int 7) ⊗ (int 8)) ⊕ (var foo))
------------------------------------
--
-- Semantyki języka
--
------------------------------------
-- Żeby poprawnie zdefniować semantyki (big- i small- step semantics)
-- potrzebujemy wprowadzić typ reprezentujący pamięć obliczeń
-- (przechowującą wartości przypisań zmiennych)
-- Store/Cntxt, czyli teoretyczny model pamięci --
data Cntxt : Set where
Ø : Cntxt
_⇉_,_ : Var → ℕ → Cntxt → Cntxt
-- przykład kontekstu
example_context = foo ⇉ 6 , ( bar ⇉ 7 , Ø )
-- typ dzięki ktoremu jestesmy w stanie wywnioskować czy dane przypisanie jest w kontekście
data _⊢_≔_ : Cntxt → Var → ℕ → Set where
top : ∀ { x } → ∀ {n} → ∀ { σ }
→ (x ⇉ n , σ) ⊢ x ≔ n
tail : ∀ { x y } → ∀ { m n } → ∀ { σ }
→ ( σ ⊢ x ≔ n )
→ ¬ ( x ≡ y ) -- dodatkowo zakładamy, że jeśli sprawdzamy, czy zmienna jest dalej w ciągu, to upewniamy się,
-- że nie jest na pierwszej pozycji
→ ( y ⇉ m , σ ) ⊢ x ≔ n
-- przykłady wnioskowania o kontekście
_ : example_context ⊢ foo ≔ 6
_ = top
_ : example_context ⊢ bar ≔ 7
_ = tail top λ ()
-- dorzucienie nowej komórki do pamięci
_⟦_≔_⟧ : Cntxt → Var → ℕ → Cntxt
σ ⟦ x ≔ n ⟧ = x ⇉ n , σ
-- Pary: pamięć, wyrażenie
Config : Set
Config = Cntxt × Exp
-- Small-step semantics--
data _↘_ : Config → Config → Set where
varred : ∀ { x : Var } → ∀ { n } → ∀ { σ : Cntxt }
→ σ ⊢ x ≔ n
------------------------------------------------------
→ ⟨ σ , var x ⟩ ↘ ⟨ σ , int n ⟩
leftadd : ∀ { σ σ' : Cntxt } → ∀ { e e' f : Exp }
→ ⟨ σ , e ⟩ ↘ ⟨ σ' , e' ⟩
------------------------------------------------------
→ ⟨ σ , e ⊕ f ⟩ ↘ ⟨ σ' , e' ⊕ f ⟩
rightadd : ∀ { σ σ' : Cntxt } → ∀ { e e' : Exp } → ∀ { n }
→ ⟨ σ , e ⟩ ↘ ⟨ σ' , e' ⟩
------------------------------------------------------
→ ⟨ σ , int n ⊕ e ⟩ ↘ ⟨ σ' , int n ⊕ e' ⟩
add : ∀ { σ : Cntxt } → ∀ { m n }
------------------------------------------------------
→ ⟨ σ , (int m) ⊕ (int n) ⟩ ↘ ⟨ σ , int ( m + n ) ⟩
leftmul : ∀ { σ σ' : Cntxt } → ∀ { e e' f : Exp }
→ ⟨ σ , e ⟩ ↘ ⟨ σ' , e' ⟩
------------------------------------------------------
→ ⟨ σ , e ⊗ f ⟩ ↘ ⟨ σ' , e' ⊗ f ⟩
rightmul : ∀ { σ σ' : Cntxt } → ∀ { e e' : Exp } → ∀ { n }
→ ⟨ σ , e ⟩ ↘ ⟨ σ' , e' ⟩
------------------------------------------------------
→ ⟨ σ , int n ⊗ e ⟩ ↘ ⟨ σ' , int n ⊗ e' ⟩
mul : ∀ { σ : Cntxt } → ∀ { m n }
------------------------------------------------------
→ ⟨ σ , (int m) ⊗ (int n) ⟩ ↘ ⟨ σ , int ( m * n ) ⟩
asg : ∀ { σ σ' : Cntxt } → ∀ { x : Var } → ∀ { n : ℕ } → ∀ { e₁ e₁' e₂ }
→ ⟨ σ , e₁ ⟩ ↘ ⟨ σ' , e₁' ⟩
------------------------------------------------------
→ ⟨ σ , (x ≔ e₁ ⨾ e₂) ⟩ ↘ ⟨ σ' , (x ≔ e₁' ⨾ e₂) ⟩
asgint : ∀ { σ : Cntxt } → ∀ { x : Var } → ∀ { n : ℕ } → ∀ { e }
------------------------------------------------------
→ ⟨ σ , x ≔ (int n) ⨾ e ⟩ ↘ ⟨ σ ⟦ x ≔ n ⟧ , e ⟩
data _↣_ : Config → Config → Set where
refl : ∀ { c } → (c ↣ c)
_andThen_ : ∀ {c c' c'' } → (c ↘ c') → (c' ↣ c'') → (c ↣ c'')
infixr 6 _andThen_
pure : ∀ { c c' } → c ↘ c' → c ↣ c'
pure x = x andThen refl
-- Przypomnijmy sobie nasze wyrażenie:
-- example₁ = foo ≔ ( int 6 ) ⨾ (((int 7) ⊗ (int 8)) ⊕ (var foo))
first_step : ⟨ Ø , example₁ ⟩ ↘ ⟨ ( foo ⇉ 6 , Ø ) , ((int 7) ⊗ (int 8)) ⊕ (var foo) ⟩
first_step = asgint
_ : ⟨ Ø , example₁ ⟩ ↣ ⟨ ( foo ⇉ 6 , Ø ) , int 62 ⟩
_ = first_step andThen
leftadd mul andThen
rightadd (varred top)
andThen pure add
-- Big-step semantics
data _≡>_ : Config → Config → Set where
intrefl : ∀ { σ } → ∀ { n }
------------------------------------------------------
→ ⟨ σ , int n ⟩ ≡> ⟨ σ , int n ⟩
varred : ∀ { x : Var } → ∀ { n } → ∀ { σ : Cntxt }
→ σ ⊢ x ≔ n
------------------------------------------------------
→ ⟨ σ , var x ⟩ ≡> ⟨ σ , int n ⟩
add : ∀ { σ σ' σ'' } → ∀ { n₁ n₂ } → ∀ { e₁ e₂ }
→ ⟨ σ , e₁ ⟩ ≡> ⟨ σ'' , int n₁ ⟩
→ ⟨ σ'' , e₂ ⟩ ≡> ⟨ σ' , int n₂ ⟩
------------------------------------------------------
→ ⟨ σ , e₁ ⊕ e₂ ⟩ ≡> ⟨ σ' , int( n₁ + n₂ ) ⟩
mul : ∀ { σ σ' σ'' } → ∀ { n₁ n₂ } → ∀ { e₁ e₂ }
→ ⟨ σ , e₁ ⟩ ≡> ⟨ σ'' , int n₁ ⟩
→ ⟨ σ'' , e₂ ⟩ ≡> ⟨ σ' , int n₂ ⟩
------------------------------------------------------
→ ⟨ σ , e₁ ⊗ e₂ ⟩ ≡> ⟨ σ' , int( n₁ * n₂ ) ⟩
asg : ∀ { σ σ' σ'' } → ∀ { n₁ n₂ } → ∀ { e₁ e₂ } → ∀ { x }
→ ⟨ σ , e₁ ⟩ ≡> ⟨ σ'' , int n₁ ⟩
→ ⟨ σ'' ⟦ x ≔ n₁ ⟧ , e₂ ⟩ ≡> ⟨ σ' , int n₂ ⟩
------------------------------------------------------
→ ⟨ σ , x ≔ e₁ ⨾ e₂ ⟩ ≡> ⟨ σ' , int n₂ ⟩
------------------------------------
--
-- Sekcja: Zgodność semantyk
--
------------------------------------
-- Lematy potrzebne do udowodnienia zgodności
lemma₁ : ∀ { σ σ' } → ∀ { n n' }
→ ⟨ σ , int n ⟩ ↣ ⟨ σ' , int n' ⟩
→ n ≡ n'
lemma₁ refl = refl
lemma₂ : ∀ { σ σ' } → ∀ { n n' }
→ ⟨ σ , int n ⟩ ↣ ⟨ σ' , int n' ⟩
→ σ ≡ σ'
lemma₂ refl = refl
lemma₃ : ∀ { σ σ' } → ∀ { m₁ m₂ n }
→ ⟨ σ , int (m₁ + m₂) ⟩ ↣ ⟨ σ' , int n ⟩
→ m₁ + m₂ ≡ n
lemma₃ refl = refl
lemma₄ : ∀ { σ σ' } → ∀ { m₁ m₂ n }
→ ⟨ σ , int (m₁ * m₂) ⟩ ↣ ⟨ σ' , int n ⟩
→ m₁ * m₂ ≡ n
lemma₄ refl = refl
lemma₅ : ∀ { σ σ' } → ∀ { e e' } → ∀ { n }
→ ⟨ σ , e ⟩ ↣ ⟨ σ' , (int n) ⟩
→ ⟨ σ , e ⊕ e' ⟩ ↣ ⟨ σ' , (int n) ⊕ e' ⟩
lemma₅ refl = refl
lemma₅ (single-step andThen step) = leftadd single-step andThen lemma₅ step
-- Zgodność semantyki small-step z big-step:
-- jeśli small-step semantics pozwala na obliczenie z e do int n (przy odpowiednich kontekstach)
-- to big-step semantics też na to pozwala:
theorem₁ : ∀ { σ σ' } → ∀ { e } → ∀ { n }
→ ⟨ σ , e ⟩ ↣ ⟨ σ' , int n ⟩
→ ⟨ σ , e ⟩ ≡> ⟨ σ' , int n ⟩
theorem₁ refl = intrefl
theorem₁ {σ} {σ'} {e} {n} (varred {x} {n₁} σ⊢x≔n₁ andThen step) rewrite lemma₁ step | lemma₂ step = varred σ⊢x≔n₁
theorem₁ (leftadd smol andThen step) = {!!}
theorem₁ (rightadd smol andThen step) = {!!}
theorem₁ {σ} {σ'} {e} {n} ((add {σ} {m₁} {m₂}) andThen step) with lemma₁ step | lemma₂ step | lemma₃ {σ} {σ'} {m₁} {m₂} {n} step
... | refl | refl | refl = add intrefl intrefl
theorem₁ (leftmul x andThen x₁) = {!!}
theorem₁ (rightmul x andThen x₁) = {!!}
theorem₁ {σ} {σ'} {e} {n} ((mul {σ} {m₁} {m₂}) andThen step) with lemma₁ step | lemma₂ step | lemma₄ {σ} {σ'} {m₁} {m₂} {n} step
... | refl | refl | refl = mul intrefl intrefl
theorem₁ {σ} {σ'} {e} {n} (asg smol andThen step) = {!!}
theorem₁ (asgint andThen step) = asg intrefl (theorem₁ step)