プログラムのランダム生成作ってみました

マルコフ連鎖を利用してプログラムをランダムに作るプログラムを作ってみました。種のプログラムを指定するとそれを元に、推移表を作ってプログラムを合成します。SEEDPROG定数に種になるプログラムのファイル名を指定します。pcompose.rbはこの生成プログラムの名前です。
PREVSTATを変えると、推移表が過去どれだけのトークンを見るかを変えられます。
ripperを使っているので、1.9以降じゃないと動かないです。

# プログラムランダム合成のテスト

require 'pp'
require 'ripper'

SEEDPROG = "pcompose.rb"
PREVSTAT = [nil, nil, nil]

class MaTable
  def initialize
    @cont = {}
  end
  def []=(keys, value)
    cc = @cont
    lkey = keys.last
    keys[0..-2].each do |k|
      cc[k] ||= {}
      cc = cc[k]
    end
    cc[lkey] ||= []
    cc[lkey].push value if !cc[lkey].include?(value)
  end

  def [](keys)
    cc = @cont
    keys[0..-2].each do |k|
      if cc[k] then
        cc = cc[k]
      end
    end
    cc[keys.last]
  end
end


mtable = MaTable.new

tokens = Ripper.tokenize(File.read(SEEDPROG))

prevtok = PREVSTAT.dup
tokens.each do |tok|
  mtable[prevtok] = tok
  prevtok.push(tok)
  prevtok.shift
end

otok = PREVSTAT.dup
endlevel = nil
while endlevel != 0 do
  toks =  mtable[otok]
  ch = rand(toks.size)
  ctok = toks[ch]

  # endlevelを動かす特殊なトークンをチェック
  case ctok
  when 'class'
  when 'module'
  when 'begin'
  when 'while'
  when 'case'
  when 'if'
  when 'do'
  when 'def'
  when '{'
    endlevel ||= 0
    endlevel += 1
    
  when '}'
  when 'end'
    if endlevel != nil then
      endlevel -= 1
    end
  end

  otok.push ctok
  otok.shift
  print ctok
end

実行例です。括弧の対応とかもうちょっと工夫が必要ですが、なかなか面白そうです。

その1

# プログラムランダム合成のテスト

require 'ripper'

SEEDPROG = @cont
    lkey = rand(toks.size)
  ctok = @cont
    keys[0..-2].each do |tok|
  mtable[otok]
  ch = cc[k]
      end
    cc = {}
  end

その2

# プログラムランダム合成のテスト

require 'pp'
require 'ripper'

SEEDPROG = "pcompose.rb"
PREVSTAT = rand(toks.size)
  prevtok.shift
  print ctok
  when '{'
    if endlevel != 0 do
  toks =  mtable[prevtok] = keys.last
    keys[0..-2].each do |tok|
  mtable[otok]
  ch = toks[ch]

class MaTable
  def initialize
    @cont = Ripper.tokenize(File.read(SEEDPROG))

prevtok = rand(toks.size)
  ctok = @cont
    keys[0..-2].each do |tok|
  mtable[prevtok] = "pcompose.rb"
PREVSTAT = tok
  prevtok.push(tok)
  prevtok.push(tok)
  end