-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathDataTypesMut.fst
46 lines (36 loc) · 1.52 KB
/
DataTypesMut.fst
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
module DataTypesMut
module B = FStar.Buffer
#push-options "--__no_positivity"
noeq
type t1 a = a * a
and t2 a =
| T2 of B.buffer (t3 a) * B.buffer (t3 Int32.t)
and t3 a =
| T3 of a * t1 Int64.t * B.buffer (t2 a) * B.buffer (t2 Int16.t)
#pop-options
(* The dependency graph is as follows:
,--------------. ,--------.
| | v |
| -> t2 Int8.t -> t3 Int8.t -----
| / | `
t2 Int8.t --> t3 Int8.t-. / |
\ | | --> t1 Int64.t <-- |
\ v | / \ |
-> t3 Int32.t -> t2 Int32.t | |
^ \ \ | | |
| -----> t2 Int16.t -> t3 Int16.t |
| | | ^ | |
`-------------'--' `-----'-------------'
But! It is not KaRaMeL's problem to guarantee that the size of any of these
types is finite (it's the C compiler's). So, we just see type monomorphization
as a graph traversal; when we hit a loop, we just insert a forward type
declaration on-the-spot and remember to visit the type we needed later on.
Note: this only works if the graph is finite. F* (happily) accepts this program:
module Test
type t a = | C: t (a * a) -> t a | D
This sends KaRaMeL into a loop... we ought to detect this.
*)
type u1 = t2 Int8.t
type u2 = t2 UInt8.t
type u3 = t3 Int16.t
let main () = 0l