Status channel in Grow()

This commit is contained in:
Ian Gulliver
2021-11-20 20:02:16 -10:00
parent 789e1e7333
commit 68ae25192e
3 changed files with 59 additions and 20 deletions

View File

@@ -6,6 +6,7 @@ import "math/rand"
import "os"
import "time"
import "github.com/firestuff/subcoding/asm"
import "github.com/firestuff/subcoding/grow"
func main() {
@@ -28,8 +29,31 @@ func main() {
log.Fatal(err)
}
_, err = def.Grow()
if err != nil {
log.Fatal(err)
statusChan := make(chan grow.Status)
go func() {
_, err = def.Grow(statusChan)
if err != nil {
log.Fatal(err)
}
}()
for {
status, ok := <-statusChan
if !ok {
break
}
if status.BestProgram == nil {
continue
}
src, err := asm.Disassemble(status.BestProgram)
if err != nil {
log.Fatal(err)
}
log.Printf("New best score %d / %d (after %d attempts):\n%s", status.BestScore, status.TargetScore, status.Attempts, src)
}
}

View File

@@ -1,44 +1,47 @@
package grow
import "log"
import "github.com/firestuff/subcoding/asm"
import "github.com/firestuff/subcoding/gen"
import "github.com/firestuff/subcoding/vm"
func (def *Definition) Grow() (*vm.Program, error) {
high_score := 0
func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
status := Status{
TargetScore: uint64(len(def.Samples)),
}
log.Print("Starting grow run...")
if statusChan != nil {
statusChan <- status
}
// TODO: Score should be number of output criteria, not number of Samples
for progs := 0; ; progs++ {
for {
status.Attempts++
prog := gen.RandProgram(def.GlobalMemorySize, def.FunctionMemorySize, def.InstructionLimit)
score, err := def.Score(prog)
if err != nil {
close(statusChan)
return nil, err
}
if score > high_score {
high_score = score
if score > status.BestScore {
status.BestScore = score
status.BestProgram = prog
src, err := asm.Disassemble(prog)
if err != nil {
return nil, err
if statusChan != nil {
statusChan <- status
}
log.Printf("New high score %d / %d (after %d attempts):\n%s", high_score, len(def.Samples), progs, src)
if score == len(def.Samples) {
if status.BestScore == status.TargetScore {
close(statusChan)
return prog, nil
}
}
}
}
func (def *Definition) Score(prog *vm.Program) (int, error) {
score := 0
func (def *Definition) Score(prog *vm.Program) (uint64, error) {
score := uint64(0)
for _, sample := range def.Samples {
state, err := vm.NewState(prog)

12
grow/status.go Normal file
View File

@@ -0,0 +1,12 @@
package grow
import "github.com/firestuff/subcoding/vm"
type Status struct {
TargetScore uint64
Attempts uint64
BestScore uint64
BestProgram *vm.Program
}