ちなみに、このPDFで書かれてる疑似コードはBNF(っぽい)
疑似コード解説
Fig2 DNAデータ型
BASE ::= I | C | F | P
DNA ::= Base* (Baseの繰り返し)
RNA ::= DNA* (DNAの繰り返し、DNAと同じ)
DNA = array<BASE>
RNA = array<DNA>
という事
Fig3 シーケンス型
X* X型の要素から成り立つシーケンス
ε 空っぽのシーケンス
x <| xs 要素x + シーケンスxsで結合する
xs |> x シーケンスxs + 要素xで結合する
xs <> ys シーケンスxs + シーケンスys
xs[m..n] xsの部分シーケンスで index m 〜 index (n-1)
xs[m..] xsの部分シーケンスで index mから最後まで(index len-1)
xs[n] xsのindex n(xs[n..(n+1)]とも書ける)。不正なindexの場合はε
len xs シーケンスxsの長さ
Fig5 DNAの実行
global dna : DNA <- ε(グローバル変数dnaを空に初期化)
global rna : RNA <- ε(グローバル変数rnaを空に初期化)
proc execute () =
dna <- read(入力を読み込む 遠藤DNAの事か)
repeat
let p <- pattern () (patternを呼び出し返値を得る)
let t <- template() (templateを呼び出し返値を得る)
matchreplace(p,t) (2つの返値を引数としてmatchreplaceを呼び出す)
end repeat
proc finish () =
write rna (rnaを書き出す)
exit ("プログラム"を終了させる)
Fig6 パターン
Pattern ::= PItem* (Pattern is array<PItem>)
PItem ::= Base (I | C | F | P 一つ)
| !N ( skip(N) )
| ?DNA ( search(DNA) )
| ( (groupのopen)
| ) (groupのend)
Fig7 Pattern評価
function pattern () : Pattern =
let p : Pattern <- ε;(Pattern型のローカル変数pを空に初期化)
let lvl: N <- 0;(現在のグループ数を表す自然数lvlを0で初期化)
repeat
case dna starts with
'C' => dna <- dna[1 . . ]; p <- p |> I
'F' => dna <- dna[1 . . ]; p <- p |> C
'P' => dna <- dna[1 . . ]; p <- p |> F
'IC' => dna <- dna[2 . . ]; p <- p |> P
'IP' => dna <- dna[2 . . ]; let n <- nat (); p <- p |> !n
'IF' => dna <- dna[3 . . ]; let s <-consts (); p <- p |> ?s
'IIP' => dna <- dna[3 . . ]; lvl <- lvl + 1; p <- p |> (
'IIC'|'IIF' => dna <- dna[3 . . ]
if lvl = 0
then return p
else lvl <- lvl -1; p <- p |> )
end if
'III' => rna <- rna |> dna[3..10];dna <- dna[10..]
anything else => finish ()
end case
end repeat
'III'の部分からも分かるが、rnaに対してdnaは要素(operator |> と <|)
なので RNA is array<DNA>
Fig9 DNAデコーディングの為の補助関数
function nat () : N = (返値は自然数)
case dna starts with
'P' => dna <- dna[1..]; return 0
'I'|'F' => dna <- dna[1..]; let n <- nat (); return 2*n
'C' => dna <- dna[1..]; let n <- nat (); return 2*n + 1
nothing (i.e., is empty) ) => finish ()
end case
function consts () : DNA = (返値はDNA)
case dna starts with
'C' => dna <- dna[1..]; let s <- consts (); return I <| s
'F' => dna <- dna[1..]; let s <- consts (); return C <| s
'P' => dna <- dna[1..]; let s <- consts (); return F <| s
'IC' => dna <- dna[2..]; let s <- consts (); return P <| s
anything else => return ε
end case
Fig10 テンプレート
Template ::= TItem*
Template is array<TItem>
TItem ::= Base(塩基)
| N^N(保護レベルlのreference numberはn^lと書かれる Nは自然数を表す)
| |N|(reference nの長さをエンコードする要素で|n|と書かれる)
Fig11 テンプレート評価
function template () : Template = (返値はTemplate)
let t : Template <- ε;
repeat
case dna starts with
'C' => dna <- dna[1..]; t <- t |> I
'F' => dna <- dna[1..]; t <- t |> C
'P' => dna <- dna[1..]; t <- t |> F
'IC' => dna <- dna[2..]; t <- t |> P
'IF'|'IP' => dna <- dna[2..]; let l <- nat (); let n <- nat (); t <- t |> n^l
'IIC'|'IIF' => dna <- dna[3..]; return t
'IIP' => dna <- dna[3..]; let n <- nat (); t <- t |> |n|
'III' => rna <- rna |> dna[3..10]; dna <- dna[10..]
anything else => finish ()
end case
end repeat
Fig12 パターンマッチング
Environment ::= DNA* (Environment is array<DNA>)
proc matchreplace (pat : Pattern, t : Template) = (引数はPattern型とTemplate型)
let i : N <- 0
let e : Environment <- ε
let c : N* <- ε (c is array<N>)
foreach p in pat(foreach文は分かる? 分からなかったらRuby,Python,C#あたりとセットでググる)
case p is of the form
b => if dna[i] = b
then i <- i + 1
else return
end if
!n => i <- i + n
if i > len(dna) then return end if
?s => if there is a smallest (n : N) such that n >= i and s is a postfix of dna[i..n]
(index i以降で最初に文字列sが出てくる場所を探し、文字列sの最後の文字のindex+1をnとする。失敗する可能性もある)
then i <- n
else return
end if
( => c <- i <| c
) => e <- e |> dna[c[0]..i]; c<-c[1..]
end case
end foreach
dna <- dna[i..]
replace(t,e)
return
Fig13 置換
proc replace (tpl:Template, e:Environment) = (引数の型はTemplate型とEnvironment型)
let r : DNA <- ε
foreach t in tpl
case t is of the form
b => r <- r |> b
n^l => r <- r <> protect(l,e[n])
|n| => r <- r <> asnat(len(e[n]))
end case
end foreach
dna <- r <> dna
return
Fig14 保護
function protect (l : N, d : DNA) : DNA = (引数の型はN,DNA 返値の型はDNA)
if l = 0
then return d
else return protect(l−1,quote(d))
end if
function quote (d : DNA) : DNA = (引数の型はDNA,返値の型はDNA)
case d starts with
I => return C <| quote(d[1..])
C => return F <| quote(d[1..])
F => return P <| quote(d[1..])
P => return 'IC' <> quote(d[1..])
anything else => return ε
end case
Fig15 自然数エンコード
function asnat (n : N) : DNA =
case n is
0 => return 'P'
positive even => return I <| asnat(floor(n/2))
positive odd => return C <| asnat(fllor(n/2))
end case
floor関数は、与えられた数を超えない最大の整数の事。
普通のプログラミング言語では 整数/整数 の演算は切り捨てられるので
単に割れば良いだけかもしれない。
ただ、 n>>1 にはするべき。
最終更新:2008年05月16日 12:11