forked from thaliaarchi/wscoq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLang.v
170 lines (163 loc) · 6.28 KB
/
Lang.v
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
Require Import Coq.ZArith.ZArith.
Require Import Coq.Strings.String.
Require Import Coq.Lists.List.
Import ListNotations.
Require Export WSpace.Bin.
Inductive inst : Type :=
| IPush (n : Z)
| IDup
| ICopy (n : nat)
| ISwap
| IDrop
| ISlide (n : nat)
| IAdd
| ISub
| IMul
| IDiv
| IMod
| IStore
| IRetrieve
| ILabel (l : bin)
| ICall (l : nat)
| IJmp (l : nat)
| IJz (l : nat)
| IJn (l : nat)
| IRet
| IEnd
| IPrintc
| IPrinti
| IReadc
| IReadi.
Inductive io : Type :=
| IOChar (c : Z)
| IOInt (n : Z).
Inductive vm : Type :=
| VM (program : list inst)
(stack : list Z)
(heap : list Z)
(stdin : list io)
(stdout : list io)
(pc : nat)
(calls : list nat).
Fixpoint store (hp : list Z) (n : nat) (x : Z) : list Z :=
match n, hp with
| O, _ :: hp' => x :: hp'
| O, [] => [x]
| S n', y :: hp' => y :: store hp' n' x
| S n', [] => 0 :: store [] n' x
end.
Definition retrieve (hp : list Z) (n : nat) : Z :=
nth_default 0 hp n.
Inductive step : vm -> vm -> Prop :=
| SPush prog stk hp sin sout pc calls n :
nth_error prog pc = Some (IPush n) ->
step (VM prog stk hp sin sout pc calls)
(VM prog (n :: stk) hp sin sout (S pc) calls)
| SDup prog x stk' hp sin sout pc calls :
nth_error prog pc = Some IDup ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog (x :: x :: stk') hp sin sout (S pc) calls)
| SCopy prog stk hp sin sout pc calls n x :
nth_error prog pc = Some (ICopy n) ->
nth_error stk n = Some x ->
step (VM prog stk hp sin sout pc calls)
(VM prog (x :: stk) hp sin sout (S pc) calls)
| SSwap prog x y stk' hp sin sout pc calls :
nth_error prog pc = Some (ISwap) ->
step (VM prog (x :: y :: stk') hp sin sout pc calls)
(VM prog (y :: x :: stk') hp sin sout (S pc) calls)
| SDrop prog x stk' hp sin sout pc calls :
nth_error prog pc = Some (IDrop) ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog stk' hp sin sout (S pc) calls)
| SSlide prog x stk' hp sin sout pc calls n :
nth_error prog pc = Some (ISlide n) ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog (x :: skipn n stk') hp sin sout (S pc) calls)
| SAdd prog y x stk' hp sin sout pc calls :
nth_error prog pc = Some IAdd ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog (x + y :: stk') hp sin sout (S pc) calls)
| SSub prog y x stk' hp sin sout pc calls :
nth_error prog pc = Some ISub ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog (x - y :: stk') hp sin sout (S pc) calls)
| SMul prog y x stk' hp sin sout pc calls :
nth_error prog pc = Some IMul ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog (x * y :: stk') hp sin sout (S pc) calls)
| SDiv prog y x stk' hp sin sout pc calls :
nth_error prog pc = Some IDiv ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog (x / y :: stk') hp sin sout (S pc) calls)
| SMod prog y x stk' hp sin sout pc calls :
nth_error prog pc = Some IMod ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog (x mod y :: stk') hp sin sout (S pc) calls)
| SStore prog y x n stk' hp sin sout pc calls :
nth_error prog pc = Some IStore ->
Z_to_nat x = Some n ->
step (VM prog (y :: x :: stk') hp sin sout pc calls)
(VM prog stk' (store hp n y) sin sout (S pc) calls)
| SRetrieve prog x n stk' hp sin sout pc calls :
nth_error prog pc = Some IRetrieve ->
Z_to_nat x = Some n ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog (retrieve hp n :: stk') hp sin sout (S pc) calls)
| SLabel prog stk hp sin sout pc calls l :
nth_error prog pc = Some (ILabel l) ->
step (VM prog stk hp sin sout pc calls)
(VM prog stk hp sin sout (S pc) calls)
| SCall prog stk hp sin sout pc calls l :
nth_error prog pc = Some (ICall l) ->
step (VM prog stk hp sin sout pc calls)
(VM prog stk hp sin sout l (S pc :: calls))
| SJmp prog stk hp sin sout pc calls l :
nth_error prog pc = Some (IJmp l) ->
step (VM prog stk hp sin sout pc calls)
(VM prog stk hp sin sout l calls)
| SJz prog x stk' hp sin sout pc calls l :
nth_error prog pc = Some (IJz l) ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog stk' hp sin sout (if x =? 0 then l else S pc) calls)
| SJn prog x stk' hp sin sout pc calls l :
nth_error prog pc = Some (IJn l) ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog stk' hp sin sout (if x <? 0 then l else S pc) calls)
| SRet prog stk hp sin sout pc l calls :
nth_error prog pc = Some IRet ->
step (VM prog stk hp sin sout pc (l :: calls))
(VM prog stk hp sin sout l calls)
| SEnd prog stk hp sin sout pc calls :
nth_error prog pc = Some IEnd ->
step (VM prog stk hp sin sout pc calls)
(VM prog stk hp sin sout (length prog) calls)
| SPrintc prog x stk' hp sin sout pc calls :
nth_error prog pc = Some IPrintc ->
step (VM prog (x :: stk') hp sin sout pc calls)
(VM prog stk' hp sin (IOChar x :: sout) (S pc) calls)
| SPrinti prog v stk' hp sin sout pc calls :
nth_error prog pc = Some IPrinti ->
step (VM prog (v :: stk') hp sin sout pc calls)
(VM prog stk' hp sin (IOInt v :: sout) (S pc) calls)
| SReadc prog x n stk' hp v sin sout pc calls :
nth_error prog pc = Some IReadc ->
Z_to_nat x = Some n ->
step (VM prog (x :: stk') hp (IOChar v :: sin) sout pc calls)
(VM prog stk' (store hp n v) sin sout (S pc) calls)
| SReadi prog x n stk' hp v sin sout pc calls :
nth_error prog pc = Some IReadi ->
Z_to_nat x = Some n ->
step (VM prog (x :: stk') hp (IOInt v :: sin) sout pc calls)
(VM prog stk' (store hp n v) sin sout (S pc) calls).
(* Equivalent to clos_refl_trans_1n in Coq.Relations.Relation_Operators. *)
Inductive execute : vm -> vm -> Prop :=
| execute_refl x :
execute x x
| execute_step x y z :
step x y ->
execute y z ->
execute x z.
Ltac execute :=
repeat (eapply execute_step; [econstructor; reflexivity | cbn]);
apply execute_refl.