-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathDoubleFFIScript.sml
142 lines (121 loc) · 4.01 KB
/
DoubleFFIScript.sml
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
(*
Logical model of the FFI calls for functions to-/fromString in
the Double module.
*)
open preamble cfFFITypeTheory cfHeapsBaseTheory DoubleProgTheory;
val _ = new_theory "DoubleFFI";
Datatype:
doubleFuns = <|
fromString : string -> word64 option;
toString : word64 -> string;
fromInt : num -> word64;
toInt : word64 -> num;
power : word64 -> word64 -> word64;
ln : word64 -> word64;
exp : word64 -> word64;
floor : word64 -> word64;
|>
End
(* a valid argument is a non-empty string with no null bytes *)
Definition validArg_def:
validArg s <=> strlen s > 0 /\ ~MEM (CHR 0) (explode s)
End
Definition into_bytes_def:
(into_bytes 0 w = []) /\
(into_bytes (SUC n) w = ((w2w w):word8) :: into_bytes n (w >>> 8))
End
Definition ffi_fromString_def:
ffi_fromString (conf: word8 list) (bytes: word8 list) doubleFns =
if LENGTH bytes = 8 then
case doubleFns.fromString (MAP (CHR o w2n) conf) of
| NONE => NONE
| SOME bs => SOME (FFIreturn (into_bytes 8 bs) doubleFns)
else NONE
End
Definition ffi_toString_def:
ffi_toString (conf: word8 list) (bytes: word8 list) doubleFns =
if LENGTH bytes = 256 then
let str = doubleFns.toString (concat_word_list (TAKE 8 bytes)) ++
[CHR 0] in
SOME (FFIreturn (MAP (n2w o ORD) str ++
DROP (LENGTH str) bytes) doubleFns)
else NONE
End
Definition ffi_toInt_def:
ffi_toInt (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition ffi_fromInt_def:
ffi_fromInt (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition ffi_pow_def:
ffi_pow (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition ffi_ln_def:
ffi_ln (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition ffi_exp_def:
ffi_exp (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition ffi_floor_def:
ffi_floor (conf: word8 list) (bytes: word8 list) doubleFns =
NONE: doubleFuns ffi_result option
End
Definition dest_iNum_def:
dest_iNum (iNum n) = n
End
(* FFI part for Double *)
Definition encode_def:
encode doubleFns =
FOLDL Cons
(Fun (\x.
case doubleFns.fromString (dest_iStr x) of
| NONE => Cons (Num 0) (Num 0)
| SOME x => Cons (Num 1) (Num (w2n x + 1))))
[Fun (\x. Str (doubleFns.toString (n2w (dest_iNum x))));
Fun (\x. Num (w2n (doubleFns.fromInt (dest_iNum x))));
Fun (\x. Num (doubleFns.toInt (n2w (dest_iNum x))));
Fun (\x. Fun (\y. Num (w2n (doubleFns.power (n2w (dest_iNum x))
(n2w (dest_iNum y))))));
Fun (\x. Num (w2n (doubleFns.ln (n2w (dest_iNum x)))));
Fun (\x. Num (w2n (doubleFns.exp (n2w (dest_iNum x)))));
Fun (\x. Num (w2n (doubleFns.floor (n2w (dest_iNum x)))))]
End
Theorem encode_11[local]:
!x y. encode x = encode y <=> x = y
Proof
rw [] \\ eq_tac \\ fs [encode_def] \\ rw []
\\ fs[FUN_EQ_THM, fetch "-" "doubleFuns_component_equality"]
\\ rw []
>- (
last_x_assum (qspec_then `iStr x'` mp_tac)
\\ gs [CaseEq "option", dest_iStr_def]
\\ rw [] \\ gs [])
\\ metis_tac [dest_iNum_def, dest_iStr_def, n2w_w2n]
QED
Theorem encode_decode_exists[local]:
?decode. !cls. decode (encode cls) = SOME cls
Proof
qexists_tac `\f. some c. encode c = f` \\ fs [encode_11]
QED
val decode_encode = new_specification(
"decode_encode",
["decode"],
encode_decode_exists);
val _ = export_rewrites ["decode_encode"];
Definition double_ffi_part_def:
double_ffi_part = (encode,decode,
[("double_fromString",ffi_fromString);
("double_toString",ffi_toString);
("double_fromInt",ffi_fromInt);
("double_toInt",ffi_toInt);
("double_pow",ffi_pow);
("double_exp",ffi_exp);
("double_ln",ffi_ln);
("double_floor",ffi_floor)])
End
val _ = export_theory ();