Browse Source

Implement operand mutation

master
Forest Belton 2 years ago
parent
commit
d4907eb204
4 changed files with 26 additions and 28 deletions
  1. +1
    -20
      ex.py
  2. +3
    -0
      gbso/cpu/insn.py
  3. +19
    -8
      gbso/program/mutate.py
  4. +3
    -0
      tests/program/test_mutate.py

+ 1
- 20
ex.py View File

@ -1,16 +1,8 @@
from gbso.cpu.insn import *
from gbso.cpu.regs import R8, R16
from gbso.optimize import (
DEFAULT_PROB_INSN,
DEFAULT_PROB_INSN_UNUSED,
DEFAULT_PROB_OPCODE,
DEFAULT_PROB_OPERAND,
DEFAULT_PROB_SWAP,
optimize,
)
from gbso.optimize import optimize
from gbso.program.program import Program
from gbso.program.mutate import mutate_program
rLCDC = 0xFF40
rIE = 0xFFFF
@ -30,14 +22,3 @@ prgm = Program(
optimized_prgm = optimize(prgm)
optimized_prgm.display()
for _ in range(10):
prgm = mutate_program(
prgm,
prob_opcode=DEFAULT_PROB_OPCODE,
prob_operand=DEFAULT_PROB_OPERAND,
prob_swap=DEFAULT_PROB_SWAP,
prob_insn=DEFAULT_PROB_INSN,
prob_insn_unused=DEFAULT_PROB_INSN_UNUSED,
)
prgm.display()

+ 3
- 0
gbso/cpu/insn.py View File

@ -1047,6 +1047,9 @@ class DEC_HL(Insn):
return "DEC (HL)"
# TODO: Implement DAA
@dataclass
class CPL(Insn):
@staticmethod

+ 19
- 8
gbso/program/mutate.py View File

@ -1,9 +1,10 @@
from dataclasses import replace
from enum import Enum
from gbso.cpu.regs import R16, R16_WITHOUT_SP, R8
from random import choice, randint, random, randrange
from typing import List, Tuple, Type, TypeVar, Union
from gbso.cpu.insn import ALL_INSN_CLASSES, Insn, Operand, UNUSED, get_signature_class
from gbso.cpu.regs import R16, R16_WITHOUT_SP, R8
from gbso.program.program import Program
@ -31,19 +32,16 @@ def mutate_program(
]
)
new_prgm = prgm
print("======")
if mutation == Mutation.OPCODE:
print("OPCODE")
new_prgm = mutate_opcode(prgm)
elif mutation == Mutation.OPERAND:
print("OPERAND")
new_prgm = mutate_operand(prgm)
elif mutation == Mutation.SWAP:
print("SWAP")
new_prgm = mutate_swap(prgm)
elif mutation == Mutation.INSTRUCTION:
print("INSN")
new_prgm = mutate_insn(prgm, prob_insn_unused)
return new_prgm
@ -57,9 +55,22 @@ def mutate_opcode(prgm: Program) -> Program:
return Program(insns=insns)
# TODO: Implement
# God, this is ugly... a better approach would be to store operands as a tuple
# instead of individual named fields.
def mutate_operand(prgm: Program) -> Program:
return prgm
insn_index = randrange(len(prgm.insns))
insn = prgm.insns[insn_index]
operand_index = randrange(len(insn.signature()))
operand_type = insn.signature()[operand_index]
operand_name = list(vars(insn).keys())[operand_index]
insns = prgm.insns.copy()
insns[insn_index] = replace(
insn, **{operand_name: create_random_operand(operand_type)}
)
return Program(insns=insns)
def mutate_swap(prgm: Program) -> Program:

+ 3
- 0
tests/program/test_mutate.py View File

@ -1,6 +1,9 @@
from gbso.cpu.insn import ADD_A_N, ADD_A_R, DEC_HL, LD_RR_NN
from gbso.program.mutate import *
# NOTE: All of these trial counts and probabilities could be a lot more precise,
# but it is easier to just throw extra trials at the problem.
def test_mutate_swap():
trials = 1000

Loading…
Cancel
Save