LoginSignup
0
0

More than 3 years have passed since last update.

決定性TMをシミュレートするシェルスクリプト

Posted at

この休日、シェルスクリプトの基本を勉強したので、その記録として、決定性TM $M=(Q,S,S,\delta,q_0,\_,F)$ をシミュレートするシェルスクリプトを作りました。

TM.sh
#!/bin/bash

# Settings
Q=(0 1 2)
S=('_' 'a' 'b')
q0=0; F=(2); L=-1; R=1;

# delta: Q×S → Q×S×{L,R}
d0_=end;        d0a=(1 'a' $R); d0b=(0 'b' $R);
d1_=(2 'a' $L); d1a=(1 'b' $R); d1b=(1 'a' $L);
d2_=end;        d2a=end;        d2b=end;

# Controller
q=$q0; w="$1"; cur=0

echo "$w: "
while
    if [ 0 -le $cur -a $cur -lt ${#w} ]; then
        c=${w:$cur:1}
    else
        c='_'
    fi
    to=($(eval echo \${d"$q$c"\[\@\]}))
    echo '(q,w,cur): '"($q,$w,$cur)"
    if [ $to = end ]; then
        break
    fi
    q=${to[0]}
    if [ 0 -le $cur -a $cur -lt ${#w} ]; then
        w=$(echo "$w" | sed -e "s/./${to[1]}/$((cur + 1))")
    elif [ $cur -lt 0 ]; then
        for ((i=0; i < -cur - 1; ++i)); do
            w='_'"$w"
        done
        w="${to[1]}$w"
        cur=0
    else
        for ((i=0; i < cur - ${#w}; ++i)); do
            w="$w"'_'
        done
        w="$w${to[1]}"
    fi
    ((cur += ${to[2]}))
    :
do :; done

for qf in "${F[@]}"; do
    if [ $qf -eq $q ]; then
        echo 'Accepted'
        exit 0
    fi
done
echo 'Rejected'
exit 1

この設定では次のようなTMを表しています:
image.png
だから、例えば、

$ bash TM.sh ab
ab: 
(q,w,cur): (0,ab,0)
(q,w,cur): (1,ab,1)
(q,w,cur): (1,aa,0)
(q,w,cur): (1,ba,1)
(q,w,cur): (1,bb,2)
(q,w,cur): (2,bba,1)
Accepted

とか、

$ bash TM.sh ababa
ababa: 
(q,w,cur): (0,ababa,0)
(q,w,cur): (1,ababa,1)
(q,w,cur): (1,aaaba,0)
(q,w,cur): (1,baaba,1)
(q,w,cur): (1,bbaba,2)
(q,w,cur): (1,bbbba,3)
(q,w,cur): (1,bbbaa,2)
(q,w,cur): (1,bbaaa,1)
(q,w,cur): (1,baaaa,0)
(q,w,cur): (1,aaaaa,-1)
(q,w,cur): (2,aaaaaa,-1)
Accepted

とか、

$ bash TM.sh bb
bb: 
(q,w,cur): (0,bb,0)
(q,w,cur): (0,bb,1)
(q,w,cur): (0,bb,2)
Rejected

など。深夜テンションで作ったので、間違い等あるかもしれません。

学べたこと

  • bashがとても書きやすいこと(算術式のfor文など)。
  • 多次元配列のサポートがないこと。
  • 外部コマンドを使うよりも組み込みのコマンドで構成したほうが随分と速いこと。特にループ中のインクリメント をexprで行うとたかだか100回のループでも体感できる程度の遅延があった。
  • 文字列の $n$ 文字目だけを置換するのが案外難しいこと。sedを使う方法しか思いつかなかった。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0