-
Notifications
You must be signed in to change notification settings - Fork 0
/
edge.sml
58 lines (51 loc) · 1.5 KB
/
edge.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
structure Edge :> sig
datatype edge = Zero | One
type edges
val ahead : edges -> edges
val direction : edges -> edge
val isDeadEnd : edges -> bool
val fromList : edge list -> edges
val toList : edges -> edge list
val fromWordAndLength : Word.word * int -> edges
val toWordAndLength : edges -> Word.word * int
val toString : edges -> string
end = struct
datatype edge = Zero | One
type edges = Word.word * int
fun ahead (w, 0) = (w, 0)
| ahead (w, len) = (w, len - 1)
fun direction (w, len) =
let
val w' = Word.>> (w, Word.fromInt (len - 1))
val d = Word.andb (w', 0w1)
in
if d = 0w0 then Zero
else One
end
fun isDeadEnd (_, 0) = true
| isDeadEnd (_, _) = false
fun lshift w = Word.<< (w, 0w1)
fun fromList' ([], w, len) = (w, len)
| fromList' (Zero::edges, w, len) =
fromList' (edges, lshift w, len + 1)
| fromList' (One::edges, w, len) =
fromList' (edges, Word.orb (lshift w, 0w1), len + 1)
fun fromList edges = fromList' (edges, 0w0, 0)
fun toList edges =
if isDeadEnd edges then []
else
let
val edge = direction edges
in
edge::toList (ahead edges)
end
fun fromWordAndLength x = x
fun toWordAndLength x = x
fun toString edges =
let
fun edgeToString Zero = "0"
| edgeToString One = "1"
in
List.foldr (fn (edge, s) => edgeToString edge ^ s) "" (toList edges)
end
end