Switch to add/remove instruction mutation

This commit is contained in:
Ian Gulliver
2021-11-22 20:33:22 -08:00
parent 8f712688b9
commit a5e44a7e07
8 changed files with 52 additions and 36 deletions

View File

@@ -2,13 +2,13 @@ package gen
import "github.com/firestuff/subcoding/vm" import "github.com/firestuff/subcoding/vm"
func randInstruction(prog *vm.Program) *vm.Instruction { func RandInstruction(prog *vm.Program) *vm.Instruction {
instr := &vm.Instruction{ instr := &vm.Instruction{
OpCode: randOpCode(), OpCode: RandOpCode(),
} }
for i, t := range vm.OperandsByOpCode[instr.OpCode] { for i, t := range vm.OperandsByOpCode[instr.OpCode] {
instr.Operands[i] = randOperand(prog, t) instr.Operands[i] = RandOperand(prog, t)
} }
return instr return instr

View File

@@ -48,7 +48,7 @@ var opCodes = []vm.OpCodeType{
vm.OpSqrt, vm.OpSqrt,
} }
func randOpCode() vm.OpCodeType { func RandOpCode() vm.OpCodeType {
// Uniform distribution // Uniform distribution
return opCodes[rand.Intn(len(opCodes))] return opCodes[rand.Intn(len(opCodes))]
} }

View File

@@ -4,7 +4,7 @@ import "math/rand"
import "github.com/firestuff/subcoding/vm" import "github.com/firestuff/subcoding/vm"
func randOperand(prog *vm.Program, t vm.OperandNumericType) *vm.Operand { func RandOperand(prog *vm.Program, t vm.OperandNumericType) *vm.Operand {
for { for {
op := &vm.Operand{ op := &vm.Operand{
Type: randOperandType(), Type: randOperandType(),

View File

@@ -1,19 +0,0 @@
package gen
import "github.com/firestuff/subcoding/vm"
func RandProgram(globalMemorySize, functionMemorySize, instructionLimit uint64) *vm.Program {
prog := &vm.Program{
GlobalMemorySize: globalMemorySize,
FunctionMemorySize: functionMemorySize,
InstructionLimit: instructionLimit,
}
prog.Functions = append(prog.Functions, &vm.Function{
Instructions: []*vm.Instruction{
randInstruction(prog),
},
})
return prog
}

View File

@@ -4,7 +4,6 @@ import "io"
import "gopkg.in/yaml.v2" import "gopkg.in/yaml.v2"
import "github.com/firestuff/subcoding/gen"
import "github.com/firestuff/subcoding/vm" import "github.com/firestuff/subcoding/vm"
type Definition struct { type Definition struct {
@@ -37,10 +36,19 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
statusChan <- status statusChan <- status
} }
prog := &vm.Program{
GlobalMemorySize: def.GlobalMemorySize,
FunctionMemorySize: def.FunctionMemorySize,
InstructionLimit: def.InstructionLimit,
Functions: []*vm.Function{
&vm.Function{},
},
}
for { for {
status.Attempts++ status.Attempts++
prog := gen.RandProgram(def.GlobalMemorySize, def.FunctionMemorySize, def.InstructionLimit) Mutate(prog)
score, err := def.score(prog) score, err := def.score(prog)
if err != nil { if err != nil {

View File

@@ -1,6 +1,6 @@
global_memory_size: 1 global_memory_size: 1
function_memory_size: 1 function_memory_size: 1
instruction_limit: 2 instruction_limit: 10
samples: samples:
- in: [0] - in: [0]
out: [0] out: [0]

36
grow/mutate.go Normal file
View File

@@ -0,0 +1,36 @@
package grow
import "math"
import "math/rand"
import "github.com/firestuff/subcoding/gen"
import "github.com/firestuff/subcoding/vm"
func Mutate(prog *vm.Program) {
target := int(math.Max(2, rand.NormFloat64()*10+15))
if len(prog.Functions[0].Instructions) < target {
addInstruction(prog, prog.Functions[0])
} else {
removeInstruction(prog, prog.Functions[0])
}
}
func addInstruction(prog *vm.Program, fnc *vm.Function) {
if len(fnc.Instructions) == 0 {
fnc.Instructions = append(fnc.Instructions, gen.RandInstruction(prog))
} else {
i := rand.Intn(len(fnc.Instructions))
fnc.Instructions = append(fnc.Instructions[:i+1], fnc.Instructions[i:]...)
fnc.Instructions[i] = gen.RandInstruction(prog)
}
}
func removeInstruction(prog *vm.Program, fnc *vm.Function) {
if len(fnc.Instructions) == 0 {
return
}
i := rand.Intn(len(fnc.Instructions))
fnc.Instructions = append(fnc.Instructions[:i], fnc.Instructions[i+1:]...)
}

View File

@@ -1,9 +0,0 @@
package test
import "testing"
import "github.com/firestuff/subcoding/gen"
func TestRandProgram(t *testing.T) {
gen.RandProgram(4, 4, 0)
}