summaryrefslogtreecommitdiff
path: root/src/nbc/gene.sml
blob: 738e3fe9460a4421795b3d9cf596f2314a0b6fb6 (plain)
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
signature GENE = sig
	val reverse: string -> string
	val first: int -> string
	val next: string -> string option
end

structure Gene :> GENE = struct
	fun reverse s =
		let
			val n = size s
			val m = n - 1
			fun opposite c = case c of
				#"A" => #"T"
				| #"T" => #"A"
				| #"C" => #"G"
				| #"G" => #"C"
				| _ => c
		in
			CharVector.tabulate (n, fn i => opposite (String.sub (s, m - i)))
		end
	fun first order = CharVector.tabulate (order, fn _ => #"A")
	fun next nmer =
		let
			val order = size nmer
			fun finish (rightmostNonT, replacement) = CharVector.tabulate (
				order
				, fn index =>
					case
						Int.compare (
							index
							, rightmostNonT
						)
					of
						LESS => String.sub (nmer, index)
						| EQUAL => replacement
						| GREATER => #"A"
			)
			fun continue index =
				if index < 0 then NONE
				else case String.sub (nmer, index) of
					#"A" => SOME (finish (index, #"C"))
					| #"C" => SOME (finish (index, #"G"))
					| #"G" => SOME (finish (index, #"T"))
					| #"T" => continue (index - 1)
					| _ => raise Fail "Invalid base"
		in
			continue (size nmer - 1)
		end
end