Files
copycat/copycat/copycat.py
2017-10-04 15:37:22 -06:00

107 lines
3.7 KiB
Python

from .coderack import Coderack
from .randomness import Randomness
from .slipnet import Slipnet
from .temperature import Temperature
from .workspace import Workspace
class Reporter(object):
"""Do-nothing base class for defining new reporter types"""
def report_answer(self, answer):
pass
def report_coderack(self, coderack):
pass
def report_slipnet(self, slipnet):
pass
def report_temperature(self, temperature): #TODO: use entropy
pass
def report_workspace(self, workspace):
pass
class Copycat(object):
def __init__(self, rng_seed=None, reporter=None):
self.coderack = Coderack(self)
self.random = Randomness(rng_seed)
self.slipnet = Slipnet()
self.temperature = Temperature() # TODO: use entropy
self.workspace = Workspace(self)
self.reporter = reporter or Reporter()
def mainLoop(self, lastUpdate):
currentTime = self.coderack.codeletsRun
self.temperature.tryUnclamp(currentTime) # TODO: use entropy
# Every 15 codelets, we update the workspace.
if currentTime >= lastUpdate + 15:
self.workspace.updateEverything()
self.coderack.updateCodelets()
self.slipnet.update(self.random)
self.temperature.update(self.workspace.getUpdatedTemperature()) # TODO: use entropy
lastUpdate = currentTime
self.reporter.report_slipnet(self.slipnet)
self.coderack.chooseAndRunCodelet()
self.reporter.report_coderack(self.coderack)
self.reporter.report_temperature(self.temperature)
self.reporter.report_workspace(self.workspace)
return lastUpdate
def runTrial(self):
"""Run a trial of the copycat algorithm"""
self.coderack.reset()
self.slipnet.reset()
self.temperature.reset() # TODO: use entropy
self.workspace.reset()
lastUpdate = float('-inf')
while self.workspace.finalAnswer is None:
lastUpdate = self.mainLoop(lastUpdate)
answer = {
'answer': self.workspace.finalAnswer,
'temp': self.temperature.last_unclamped_value, # TODO: use entropy
'time': self.coderack.codeletsRun,
}
self.reporter.report_answer(answer)
return answer
def run(self, initial, modified, target, iterations, testAdjFormulas=False):
self.workspace.resetWithStrings(initial, modified, target)
# I (LSaldyt) am very sorry for writing code like this.
# It will soon be deleted. I promise.
if testAdjFormulas:
formulas = self.temperature.adj_formulas()
else:
formulas = ['original']
formulaList = []
for formula in formulas:
self.temperature.useAdj(formula)
answers = {}
for i in range(iterations):
answer = self.runTrial()
d = answers.setdefault(answer['answer'], {
'count': 0,
'sumtemp': 0, # TODO: use entropy
'sumtime': 0
})
d['count'] += 1
d['sumtemp'] += answer['temp'] # TODO: use entropy
d['sumtime'] += answer['time']
for answer, d in answers.items():
d['avgtemp'] = d.pop('sumtemp') / d['count']
d['avgtime'] = d.pop('sumtime') / d['count']
formulaList.append((formula, answers))
if not testAdjFormulas:
return formulaList[0][1]
else:
return formulaList
def run_forever(self, initial, modified, target):
self.workspace.resetWithStrings(initial, modified, target)
while True:
self.runTrial()