4 meta compute_max_steps 0x10000
12 use logic.Compiler_logic
14 function ifun_post (f:machine_state -> machine_state) : post 'a =
15 \x p mc mc'. let VMC p s m c = mc in
16 let VMC p' s' m' c' = mc' in VMS p' s' m' = f (VMS p s m) /\ c' = c + 1
17 meta rewrite_def function ifun_post
19 let ifunf (ghost pre:pre 'a) (code_f:code)
20 (ghost f:machine_state -> machine_state) : hl 'a
21 requires { forall c p. codeseq_at c p code_f ->
22 forall x ms clock. let VMS p' s m = ms in
23 pre x p (VMC p' s m clock) -> transition c ms (f ms) }
24 ensures { result.pre = pre /\ result.post = ifun_post f }
25 ensures { result.code = code_f /\ hl_correctness result }
26 = let res = { pre = pre; code = code_f; post = ifun_post f } in
27 assert { forall x:'a,c_glob p mc mc'. res.pre x p mc ->
28 codeseq_at c_glob p res.code ->
29 let post = res.post x p mc in
30 C.transition_star (c_glob,post) mc mc' /\ not post mc' ->
31 let VMC p s m _ = mc' in
34 mc = mc' && transition c_glob (VMS p s m) ms' };
38 function iconst_post (n:int) : post 'a =
39 \x p ms ms'. forall s m clock. ms = VMC p s m clock ->
40 ms' = VMC (p+1) (push n s) m (clock+1)
41 meta rewrite_def function iconst_post
43 function iconst_fun (n:int) : machine_state -> machine_state =
44 \ms. let VMS p s m = ms in VMS (p+1) (push n s) m
45 meta rewrite_def function iconst_fun
47 let iconstf (n: int) : hl 'a
48 ensures { result.pre = trivial_pre /\ result.post = iconst_post n }
49 ensures { result.code.length = 1 /\ hl_correctness result }
50 = hoare trivial_pre ($ ifunf trivial_pre n.iconst n.iconst_fun) n.iconst_post
53 function ivar_post (x:id) : post 'a =
54 \a p ms ms'. forall s m clock.
55 ms = VMC p s m clock -> ms' = VMC (p+1) (push m[x] s) m (clock+1)
56 meta rewrite_def function ivar_post
58 function ivar_fun (x:id) : machine_state -> machine_state =
59 \ms. let VMS p s m = ms in VMS (p+1) (push m[x] s) m
60 meta rewrite_def function ivar_fun
62 let ivarf (x: id) : hl 'a
63 ensures { result.pre = trivial_pre /\ result.post = ivar_post x }
64 ensures { result.code.length = 1 /\ hl_correctness result }
65 = hoare trivial_pre ($ ifunf trivial_pre x.ivar x.ivar_fun) x.ivar_post
67 (* Binary arithmetic operators specification (Iadd, Isub, Imul) *)
68 type binop = int -> int -> int
70 constant ibinop_pre : pre 'a =
71 \x p ms . exists n1 n2 s m clock. ms = VMC p (push n2 (push n1 s)) m clock
72 meta rewrite_def function ibinop_pre
74 function ibinop_post (op : binop) : post 'a =
75 \x p ms ms'. forall n1 n2 s m clk. ms = VMC p (push n2 (push n1 s)) m clk ->
76 ms' = VMC (p+1) (push (op n1 n2) s) m (clk+1)
77 meta rewrite_def function ibinop_post
79 function ibinop_fun (op:binop) : machine_state -> machine_state =
81 | VMS p (Cons n2 (Cons n1 s)) m -> VMS (p+1) (push (op n1 n2) s) m
84 meta rewrite_def function ibinop_fun
86 let create_binop (code_b:code) (ghost op:binop) : hl 'a
87 requires { forall c p. codeseq_at c p code_b ->
88 forall n1 n2 s m. transition c (VMS p (push n2 (push n1 s)) m)
89 (VMS (p+1) (push (op n1 n2) s) m) }
90 ensures { result.pre = ibinop_pre /\ result.post = ibinop_post op }
91 ensures { result.code.length = code_b.length /\ hl_correctness result }
92 = hoare ibinop_pre ($ ifunf ibinop_pre code_b op.ibinop_fun) op.ibinop_post
94 constant plus : binop = \x y. x + y
95 meta rewrite_def function plus
97 constant sub : binop = \x y. x - y
98 meta rewrite_def function sub
100 constant mul : binop = \x y. x * y
101 meta rewrite_def function mul
104 ensures { result.pre = ibinop_pre /\ result.post = ibinop_post plus }
105 ensures { result.code.length = 1 /\ hl_correctness result}
106 = create_binop iadd plus
109 ensures { result.pre = ibinop_pre /\ result.post = ibinop_post sub }
110 ensures { result.code.length = 1 /\ hl_correctness result}
111 = create_binop isub sub
114 ensures { result.pre = ibinop_pre /\ result.post = ibinop_post mul }
115 ensures { result.code.length = 1 /\ hl_correctness result}
116 = create_binop imul mul
119 function inil_post : post 'a =
120 \x p mc mc'. mc = mc'
121 meta rewrite_def function inil_post
124 ensures { result.pre = trivial_pre /\ result.post = inil_post }
125 ensures { result.code.length = 0 /\ hl_correctness result }
126 = { pre = trivial_pre; code = Nil; post = inil_post }
128 (* Ibranch specification *)
129 function ibranch_post (ofs: pos) : post 'a =
130 \x p ms ms'. forall s m clk. ms = VMC p s m clk ->
131 ms' = VMC (p + 1 + ofs) s m (clk+1)
132 meta rewrite_def function ibranch_post
134 function ibranch_fun (ofs:pos) : machine_state -> machine_state =
135 \ms. let VMS p s m = ms in VMS (p+1+ofs) s m
136 meta rewrite_def function ibranch_fun
138 let ibranchf (ofs:pos) : hl 'a
139 ensures { result.pre = trivial_pre /\ result.post = ibranch_post ofs }
140 ensures { result.code.length = 1 /\ hl_correctness result }
141 = let cf = $ ifunf trivial_pre (ibranch ofs) (ibranch_fun ofs) in
142 hoare trivial_pre cf (ibranch_post ofs)
144 type cond = int -> int -> bool
146 function icjump_post (cond:cond) (ofs:int) : post 'a =
147 \x p ms ms'. forall n1 n2 s m c. ms = VMC p (push n2 (push n1 s)) m c ->
148 (cond n1 n2 -> ms' = VMC (p + ofs + 1) s m (c+1)) /\
149 (not cond n1 n2 -> ms' = VMC (p+1) s m (c+1))
150 meta rewrite_def function icjump_post
152 function icjump_fun (cond:cond) (ofs:int) : machine_state -> machine_state =
154 | VMS p (Cons n2 (Cons n1 s)) m ->
155 if cond n1 n2 then VMS (p+ofs+1) s m else VMS (p+1) s m
159 let create_cjump (code_cd:code) (ghost cond:cond) (ghost ofs:pos) : hl 'a
160 requires { forall c p1 n1 n2. codeseq_at c p1 code_cd ->
161 let p2 = (if cond n1 n2 then p1 + 1 + ofs else p1 + 1) in
162 forall s m. transition c (VMS p1 (push n2 (push n1 s)) m) (VMS p2 s m) }
163 ensures { result.pre = ibinop_pre /\ result.post = icjump_post cond ofs }
164 ensures { result.code.length = code_cd.length /\ hl_correctness result }
165 = let c = $ ifunf ibinop_pre code_cd (icjump_fun cond ofs) in
166 hoare ibinop_pre c (icjump_post cond ofs)
168 (* binary Boolean operators specification (Ibeq, Ibne, Ible, Ibgt) *)
169 constant beq : cond = \x y. x = y
170 meta rewrite_def function beq
172 constant bne : cond = \x y. x <> y
173 meta rewrite_def function bne
175 constant ble : cond = \x y. x <= y
176 meta rewrite_def function ble
178 constant bgt : cond = \x y. x > y
179 meta rewrite_def function bgt
181 let ibeqf (ofs : pos) : hl 'a
182 ensures { result.pre = ibinop_pre /\ result.post = icjump_post beq ofs }
183 ensures { result.code.length = 1 /\ hl_correctness result }
184 = create_cjump (ibeq ofs) beq ofs
186 let ibnef (ofs : pos) : hl 'a
187 ensures { result.pre = ibinop_pre /\ result.post = icjump_post bne ofs }
188 ensures { result.code.length = 1 /\ hl_correctness result }
189 = create_cjump (ibne ofs) bne ofs
191 let iblef (ofs : pos) : hl 'a
192 ensures { result.pre = ibinop_pre /\ result.post = icjump_post ble ofs }
193 ensures { result.code.length = 1 /\ hl_correctness result }
194 = create_cjump (ible ofs) ble ofs
196 let ibgtf (ofs : pos) : hl 'a
197 ensures { result.pre = ibinop_pre /\ result.post = icjump_post bgt ofs }
198 ensures { result.code.length = 1 /\ hl_correctness result }
199 = create_cjump (ibgt ofs) bgt ofs
201 constant isetvar_pre : pre 'a =
202 \x p mc . exists n s m c. mc = VMC p (push n s) m c
203 meta rewrite_def function isetvar_pre
205 function isetvar_post (x:id) : post 'a =
206 \a p ms ms'. forall s n m c.
207 ms = VMC p (push n s) m c -> ms' = VMC (p+1) s m[x <- n] (c+1)
208 meta rewrite_def function isetvar_post
210 function isetvar_fun (x:id) : machine_state -> machine_state =
212 | VMS p (Cons n s) m -> VMS (p+1) s m[x <- n]
215 meta rewrite_def function isetvar_fun
217 let isetvarf (x: id) : hl 'a
218 ensures { result.pre = isetvar_pre /\ result.post = isetvar_post x }
219 ensures { result.code.length = 1 /\ hl_correctness result }
220 = let c = $ ifunf isetvar_pre (isetvar x) (isetvar_fun x) in
221 hoare isetvar_pre c (isetvar_post x)
227 compile-command: "why3 ide -L . specs.mlw"