Skip to content

Commit c15e096

Browse files
committed
[lec13] live coding Agda result
1 parent 1a93fac commit c15e096

File tree

2 files changed

+273
-1
lines changed

2 files changed

+273
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Material: plt = course book, dragon = Dragon book. Slides follow closely the plt
5959
| Tue 10/12 | 13-15 | Type inference and polymorphism | plt 7.7-9, [script](notes/typing.html), [visualization tool](https://github.com/teach-plt/visualize-type-inference) |
6060
| Thu 12/12 **HC1** | 13-14 | Hands-on with Lab 4 (Haskell) | [live code](live/2024/lab4/Interpreter.hs) |
6161
| Thu 12/12 | 14-15 | Hands-on with Lab 4 (Java) | [live code](live/2024/lab4/Interpreter.java) |
62-
| Tue 17/12 | 13-15 | Dependent types (Agda) | live coding [start](live/2024/agda/JVM-start.agda) |
62+
| Tue 17/12 | 13-15 | Dependent types (Agda) | live coding [start](live/2024/agda/JVM-start.agda) [stop](live/2024/agda/JVM.agda) |
6363
| *Wed 18/12* | *23* | *Lab 3 deadline* | |
6464
| Thu 19/12 **SB-H5** | 13-15 | Preparing for the exam | |
6565

live/2024/agda/JVM.agda

+272
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
-- Programming Language Technology DAT151/DIT231
2+
-- 2024-12-17 Agda (version ≥2.6.0)
3+
-- From Dependent Types to Verified Compilation
4+
5+
-- A correct compiler for Hutton's Razor to a stack machine
6+
7+
-- Similar to an early pen-and-paper proof (register machine):
8+
--
9+
-- John McCarthy and James Painter, 1967
10+
-- Correctness of a Compiler for Arithmetic Expressions
11+
-- http://jmc.stanford.edu/articles/mcpain/mcpain.pdf
12+
13+
open import Relation.Binary.PropositionalEquality
14+
open ≡-Reasoning
15+
16+
-- Data types and pattern matching
17+
---------------------------------------------------------------------------
18+
19+
-- Example of a data type.
20+
21+
data List (A : Set) : Set where
22+
[] : List A
23+
_∷_ : (x : A) (xs : List A) List A -- \ : : A → List A → List A
24+
25+
-- Natural numbers in unary notation.
26+
27+
data Nat : Set where
28+
zero : Nat
29+
suc : (n : Nat) Nat
30+
31+
{-# BUILTIN NATURAL Nat #-}
32+
33+
-- NATURAL gives us decimal notation for Nat.
34+
35+
five = suc 4
36+
37+
infixl 10 _+_
38+
infixr 6 _∷_
39+
40+
-- Addition.
41+
42+
_+_ : (n m : Nat) Nat
43+
zero + m = m
44+
suc n + m = suc (n + m)
45+
46+
{-
47+
data Empty : Set where
48+
49+
inh : Empty
50+
inh = error "hoo"
51+
-}
52+
53+
plus-0 : (n : Nat) n + zero ≡ n -- \ = =
54+
plus-0 zero = refl {x = 0}
55+
plus-0 (suc n) = cong suc (plus-0 n)
56+
57+
-- Indexed types: Fin, Vec
58+
---------------------------------------------------------------------------
59+
60+
-- Bounded numbers: Fin n = { m | m < n }.
61+
62+
data Fin : Nat Set where
63+
zero : {n : Nat} Fin (suc n)
64+
suc : {n : Nat} (i : Fin n) Fin (suc n)
65+
66+
-- Example with hidden arguments.
67+
68+
three : Fin 5
69+
three = suc {n = 4} (suc (suc zero))
70+
71+
-- Vectors (length-indexed lists).
72+
-- Vec : Set → Nat → Set
73+
74+
data Vec (A : Set) : Nat Set where
75+
[] : Vec A zero
76+
_∷_ : {n : Nat} (x : A) (xs : Vec A n) Vec A (suc n)
77+
78+
-- Automatic quantification over hidden arguments.
79+
80+
variable
81+
n : Nat
82+
A : Set
83+
84+
-- Reading an element of a vector.
85+
86+
lookup : {n : Nat} {A : Set} (i : Fin n) (xs : Vec A n) A
87+
lookup zero (x ∷ xs) = x
88+
lookup (suc i) (x ∷ xs) = lookup i xs
89+
90+
-- Expressions and interpretation: "Hutton's razor"
91+
---------------------------------------------------------------------------
92+
93+
-- We have a single type of (natural) numbers.
94+
95+
Num = Nat
96+
97+
-- Expressions over n variables.
98+
99+
-- A variable is denoted by its number x < n.
100+
101+
data Exp (n : Nat) : Set where
102+
var : (x : Fin n) Exp n
103+
num : (w : Num) Exp n
104+
plus : (e e' : Exp n) Exp n
105+
106+
-- (x + 3) + y
107+
ex1 : Exp 2
108+
ex1 = plus (plus (var zero) (num 3)) (var (suc zero))
109+
110+
-- An environment maps each variable to its value.
111+
112+
Value = Num
113+
Env = Vec Num
114+
115+
-- Interpretation of expressions.
116+
117+
eval : (e : Exp n) (γ : Env n) Value
118+
eval (var x) γ = lookup x γ
119+
eval (num w) γ = w
120+
eval (plus e e₁) γ = eval e γ + eval e₁ γ
121+
122+
v1 = eval ex1 (151 ∷ [])
123+
124+
-- A fragment of JVM
125+
---------------------------------------------------------------------------
126+
127+
StackSize = Nat -- Current stack size
128+
StoreSize = Nat -- Local variable store limit
129+
Addr = Fin -- Local variable address
130+
Word = Nat -- Word (should be 32bit signed int, but we use Nat here)
131+
132+
-- JVM instructions.
133+
--
134+
-- n = number of local variables
135+
-- m = stack size before instruction
136+
-- m' = stack size after instruction
137+
138+
variable
139+
k l m m' : StackSize
140+
141+
data Ins (n : StoreSize) : (m m' : StackSize) Set where
142+
load : (a : Addr n) Ins n m (1 + m) -- Load variable onto stack.
143+
add : Ins n (2 + m) (1 + m) -- Add top stack elements.
144+
ldc : (w : Word) Ins n m (1 + m) -- Load constant onto stack.
145+
pop : Ins n (1 + m) m -- Remove top stack element.
146+
147+
-- Instruction sequences.
148+
-- Note that for instruction concatenation, the index "l" has to match.
149+
150+
data Inss (n : StoreSize) (m : StackSize) : (m' : StackSize) Set where
151+
[] : Inss n m m
152+
ins : Ins n m l Inss n m l
153+
_∙_ : (i : Inss n m l) (is : Inss n l k) Inss n m k
154+
155+
infixr 10 _∙_
156+
157+
-- Compilation of expressions
158+
---------------------------------------------------------------------------
159+
160+
-- The code for an expression leaves one additional value on the stack.
161+
162+
compile : (e : Exp n) Inss n m (suc m)
163+
compile (var x) = ins (load x)
164+
compile (num w) = ins (ldc w)
165+
compile (plus e e') = compile e ∙ compile e' ∙ ins add
166+
167+
ss1 : Inss 2 0 1
168+
ss1 = compile ex1
169+
170+
-- JVM small-step semantics
171+
---------------------------------------------------------------------------
172+
173+
-- JVM machine state (simplified).
174+
175+
Store = Env
176+
Stack = Vec Word
177+
178+
record State (n : StoreSize) (m : StackSize) : Set where
179+
constructor state
180+
field
181+
V : Store n
182+
S : Stack m
183+
open State
184+
185+
-- Executing a JVM instruction.
186+
187+
step : (i : Ins n m m') (s : State n m) State n m'
188+
step (load a) (state V S) = state V (lookup a V ∷ S)
189+
step add (state V (v ∷ w ∷ S)) = state V (w + v ∷ S)
190+
step (ldc w) (state V S) = state V (w ∷ S)
191+
step pop (state V (_ ∷ S)) = state V S
192+
193+
-- Compiler correctness
194+
---------------------------------------------------------------------------
195+
196+
-- Executing a series of JVM instructions.
197+
198+
steps : (is : Inss n m m') (s : State n m) State n m'
199+
steps (ins i) s = step i s
200+
steps [] s = s
201+
steps (is ∙ is') s = steps is' (steps is s)
202+
203+
r1 = steps ss1 (state (151 ∷ []) [])
204+
205+
-- Pushing a word onto the stack.
206+
207+
push : Word State n m State n (suc m)
208+
push w (state V S) = state V (w ∷ S)
209+
210+
push-eval : (e : Exp n) (s : State n m) State n (suc m)
211+
push-eval e (state V S) = state V (eval e V ∷ S)
212+
213+
214+
-- Compiler correctness theorem.
215+
216+
-- Running the instructions for an expression e
217+
-- leaves the value of e on top of the stack.
218+
219+
sound : (e : Exp n) (s : State n m)
220+
221+
steps (compile e) s ≡ push-eval e s
222+
223+
-- Case: variables
224+
sound (var x) s = refl
225+
226+
-- Case: number literals.
227+
sound (num w) s = refl
228+
229+
-- Case: addition expression.
230+
sound (plus e e') s = begin
231+
steps (compile (plus e e')) s ≡⟨ refl ⟩
232+
steps (compile e ∙ compile e' ∙ ins add) s ≡⟨ refl ⟩
233+
steps (compile e' ∙ ins add) (steps (compile e) s) ≡⟨ cong (steps _) (sound e s) ⟩
234+
steps (compile e' ∙ ins add) s' ≡⟨ refl ⟩
235+
steps (ins add) (steps (compile e') s') ≡⟨ cong (steps _) (sound e' s) ⟩
236+
steps (ins add) (push-eval e' s') ≡⟨ {! !}
237+
push-eval (plus e e') s
238+
239+
where s' = push-eval e s
240+
241+
-- steps (compile (plus e e') s)
242+
-- = steps (compile e ∙ compile e' ∙ ins add) s
243+
-- = steps (compile e' ∙ ins add) (steps (compile e) s) -- by ind.hyp.
244+
-- = steps (compile e' ∙ ins add) (push-eval e s)
245+
-- = steps (ins add) (steps (compile e') (push-eval e s))
246+
-- = steps (ins add) (push-eval e' (push-eval e s))
247+
-- = step add (push-eval e' (push-eval e s))
248+
-- = step add (push-eval e' (push-eval e (state V S))) -- s =: state V S
249+
-- = step add (push-eval e' (state V (eval e V ∷ S)))
250+
-- = step add (state V (eval e' V ∷ eval e V ∷ S))
251+
-- = state V ((eval e V + eval e' V) ∷ S)
252+
-- = state V (eval (plus e e') V ∷ S)
253+
-- = push-eval (plus e e') (state V S)
254+
-- = push-eval (plus e e') s
255+
256+
-- -}
257+
-- -}
258+
-- -}
259+
-- -}
260+
-- -}
261+
-- -}
262+
-- -}
263+
-- -}
264+
-- -}
265+
-- -}
266+
-- -}
267+
-- -}
268+
-- -}
269+
-- -}
270+
-- -}
271+
-- -}
272+
-- -}

0 commit comments

Comments
 (0)