Massive overhaul of "codelet methods" and the coderack.

Should be no functional change, but this gets rid of one circular
import (some codelet methods need a pointer to the coderack, but
they should be getting that pointer from their caller, not from
the global scope) and a lot of reflection-magic.
This commit is contained in:
Arthur O'Dwyer
2017-04-16 21:12:39 -07:00
parent f37b88d032
commit a3b122b75c
2 changed files with 80 additions and 107 deletions

View File

@ -1,15 +1,12 @@
import random
import inspect
import logging
import random
from slipnet import slipnet
import temperature
import formulas
from workspaceFormulas import chooseDirectedNeighbor
from workspaceFormulas import chooseNeighbor
from coderack import coderack
from workspaceObject import WorkspaceObject
from letter import Letter
from replacement import Replacement
@ -21,6 +18,14 @@ from correspondence import Correspondence
from workspaceFormulas import chooseUnmodifiedObject
from workspaceFormulas import chooseBondFacet
def codelet(name):
"""Decorator for otherwise-unused functions that are in fact used as codelet behaviors"""
def wrap(f):
assert tuple(inspect.getargspec(f)) == (['coderack', 'codelet'], None, None, None)
f.is_codelet_method = True
f.codelet_name = name
return f
return wrap
# some methods common to the codelets
def __showWhichStringObjectIsFrom(structure):
@ -123,8 +128,8 @@ def __slippability(conceptMappings):
return False
# start the actual codelets
def breaker():
@codelet('breaker')
def breaker(coderack, codelet):
probabilityOfFizzle = (100.0 - formulas.Temperature) / 100.0
assert not formulas.coinFlip(probabilityOfFizzle)
# choose a structure at random
@ -148,7 +153,8 @@ def breaker():
structure.break_the_structure()
def bottom_up_description_scout(codelet):
@codelet('bottom-up-description-scout')
def bottom_up_description_scout(coderack, codelet):
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
assert chosenObject
__showWhichStringObjectIsFrom(chosenObject)
@ -165,7 +171,8 @@ def bottom_up_description_scout(codelet):
chosenProperty, codelet)
def top_down_description_scout(codelet):
@codelet('top-down-description-scout')
def top_down_description_scout(coderack, codelet):
descriptionType = codelet.arguments[0]
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
assert chosenObject
@ -179,7 +186,8 @@ def top_down_description_scout(codelet):
chosenProperty, codelet)
def description_strength_tester(codelet):
@codelet('description-strength-tester')
def description_strength_tester(coderack, codelet):
description = codelet.arguments[0]
description.descriptor.buffer = 100.0
description.updateStrength()
@ -189,7 +197,8 @@ def description_strength_tester(codelet):
coderack.newCodelet('description-builder', codelet, strength)
def description_builder(codelet):
@codelet('description-builder')
def description_builder(coderack, codelet):
description = codelet.arguments[0]
assert description.object in workspace.objects
if description.object.described(description.descriptor):
@ -199,7 +208,8 @@ def description_builder(codelet):
description.build()
def bottom_up_bond_scout(codelet):
@codelet('bottom-up-bond-scout')
def bottom_up_bond_scout(coderack, codelet):
source = chooseUnmodifiedObject('intraStringSalience', workspace.objects)
__showWhichStringObjectIsFrom(source)
destination = chooseNeighbor(source)
@ -222,7 +232,8 @@ def bottom_up_bond_scout(codelet):
sourceDescriptor, destinationDescriptor, codelet)
def rule_scout(codelet):
@codelet('rule-scout')
def rule_scout(coderack, codelet):
assert workspace.numberOfUnreplacedObjects() == 0
changedObjects = [o for o in workspace.initial.objects if o.changed]
#assert len(changedObjects) < 2
@ -284,7 +295,8 @@ def rule_scout(codelet):
slipnet.letter, relation, codelet)
def rule_strength_tester(codelet):
@codelet('rule-strength-tester')
def rule_strength_tester(coderack, codelet):
rule = codelet.arguments[0]
rule.updateStrength()
probability = formulas.temperatureAdjustedProbability(
@ -293,7 +305,8 @@ def rule_strength_tester(codelet):
coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule)
def replacement_finder():
@codelet('replacement-finder')
def replacement_finder(coderack, codelet):
# choose random letter in initial string
letters = [o for o in workspace.initial.objects if isinstance(o, Letter)]
letterOfInitialString = random.choice(letters)
@ -330,7 +343,8 @@ def replacement_finder():
logging.info('building replacement')
def top_down_bond_scout__category(codelet):
@codelet('top-down-bond-scout--category')
def top_down_bond_scout__category(coderack, codelet):
logging.info('top_down_bond_scout__category')
category = codelet.arguments[0]
source = __getScoutSource(category, formulas.localBondCategoryRelevance,
@ -358,7 +372,8 @@ def top_down_bond_scout__category(codelet):
sourceDescriptor, codelet)
def top_down_bond_scout__direction(codelet):
@codelet('top-down-bond-scout--direction')
def top_down_bond_scout__direction(coderack, codelet):
direction = codelet.arguments[0]
source = __getScoutSource(
direction, formulas.localDirectionCategoryRelevance, 'bond')
@ -376,7 +391,8 @@ def top_down_bond_scout__direction(codelet):
sourceDescriptor, destinationDescriptor, codelet)
def bond_strength_tester(codelet):
@codelet('bond-strength-tester')
def bond_strength_tester(coderack, codelet):
bond = codelet.arguments[0]
__showWhichStringObjectIsFrom(bond)
bond.updateStrength()
@ -391,7 +407,8 @@ def bond_strength_tester(codelet):
coderack.newCodelet('bond-builder', codelet, strength)
def bond_builder(codelet):
@codelet('bond-builder')
def bond_builder(coderack, codelet):
bond = codelet.arguments[0]
__showWhichStringObjectIsFrom(bond)
bond.updateStrength()
@ -433,7 +450,8 @@ def bond_builder(codelet):
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
def top_down_group_scout__category(codelet):
@codelet('top-down-group-scout--category')
def top_down_group_scout__category(coderack, codelet):
groupCategory = codelet.arguments[0]
category = groupCategory.getRelatedNode(slipnet.bondCategory)
assert category
@ -515,7 +533,8 @@ def top_down_group_scout__category(codelet):
direction, bondFacet, codelet)
def top_down_group_scout__direction(codelet):
@codelet('top-down-group-scout--direction')
def top_down_group_scout__direction(coderack, codelet):
direction = codelet.arguments[0]
source = __getScoutSource(direction,
formulas.localDirectionCategoryRelevance,
@ -606,7 +625,8 @@ def top_down_group_scout__direction(codelet):
#noinspection PyStringFormat
def group_scout__whole_string(codelet):
@codelet('group-scout--whole-string')
def group_scout__whole_string(coderack, codelet):
string = workspace.initial
if random.random() > 0.5:
string = workspace.target
@ -646,7 +666,8 @@ def group_scout__whole_string(codelet):
bondFacet, codelet)
def group_strength_tester(codelet):
@codelet('group-strength-tester')
def group_strength_tester(coderack, codelet):
# update strength value of the group
group = codelet.arguments[0]
__showWhichStringObjectIsFrom(group)
@ -661,7 +682,8 @@ def group_strength_tester(codelet):
coderack.newCodelet('group-builder', codelet, strength)
def group_builder(codelet):
@codelet('group-builder')
def group_builder(coderack, codelet):
# update strength value of the group
group = codelet.arguments[0]
#print '%s' % group
@ -735,7 +757,8 @@ def group_builder(codelet):
logging.info('building group')
def rule_builder(codelet):
@codelet('rule-builder')
def rule_builder(coderack, codelet):
rule = codelet.arguments[0]
if rule.ruleEqual(workspace.rule):
rule.activateRuleDescriptions()
@ -768,7 +791,8 @@ def __getCutOff(density):
return len(distribution)
def rule_translator():
@codelet('rule-translator')
def rule_translator(coderack, codelet):
assert workspace.rule
if len(workspace.initial) == 1 and len(workspace.target) == 1:
bondDensity = 1.0
@ -789,7 +813,8 @@ def rule_translator():
formulas.Temperature = 100.0
def bottom_up_correspondence_scout(codelet):
@codelet('bottom-up-correspondence-scout')
def bottom_up_correspondence_scout(coderack, codelet):
objectFromInitial = chooseUnmodifiedObject('interStringSalience',
workspace.initial.objects)
objectFromTarget = chooseUnmodifiedObject('interStringSalience',
@ -826,7 +851,8 @@ def bottom_up_correspondence_scout(codelet):
conceptMappings, flipTargetObject, codelet)
def important_object_correspondence_scout(codelet):
@codelet('important-object-correspondence-scout')
def important_object_correspondence_scout(coderack, codelet):
objectFromInitial = chooseUnmodifiedObject('relativeImportance',
workspace.initial.objects)
descriptors = objectFromInitial.relevantDistinguishingDescriptors()
@ -876,7 +902,8 @@ def important_object_correspondence_scout(codelet):
conceptMappings, flipTargetObject, codelet)
def correspondence_strength_tester(codelet):
@codelet('correspondence-strength-tester')
def correspondence_strength_tester(coderack, codelet):
correspondence = codelet.arguments[0]
objectFromInitial = correspondence.objectFromInitial
objectFromTarget = correspondence.objectFromTarget
@ -899,7 +926,8 @@ def correspondence_strength_tester(codelet):
strength, correspondence)
def correspondence_builder(codelet):
@codelet('correspondence-builder')
def correspondence_builder(coderack, codelet):
correspondence = codelet.arguments[0]
objectFromInitial = correspondence.objectFromInitial
objectFromTarget = correspondence.objectFromTarget

View File

@ -1,9 +1,8 @@
import re
import inspect
import math
import logging
import random
import codeletMethods
import formulas
import workspaceFormulas
from slipnet import slipnet
@ -24,18 +23,17 @@ def getUrgencyBin(urgency):
class CodeRack(object):
def __init__(self):
self.speedUpBonds = False
self.removeBreakerCodelets = False
self.removeTerracedScan = False
self.pressures = CoderackPressures()
self.pressures.initialisePressures()
self.reset()
self.initialCodeletNames = ('bottom-up-bond-scout',
'replacement-finder',
'bottom-up-correspondence-scout')
self.codeletMethodsDir = None
self.initialCodeletNames = (
'bottom-up-bond-scout',
'replacement-finder',
'bottom-up-correspondence-scout',
)
self.runCodelets = {}
self.postings = {}
self.getCodeletMethods()
def reset(self):
self.codelets = []
@ -87,17 +85,11 @@ class CodeRack(object):
self.__postBottomUpCodelets('replacement-finder')
self.__postBottomUpCodelets('rule-scout')
self.__postBottomUpCodelets('rule-translator')
if not self.removeBreakerCodelets:
self.__postBottomUpCodelets('breaker')
self.__postBottomUpCodelets('breaker')
def __postBottomUpCodelets(self, codeletName):
probability = workspaceFormulas.probabilityOfPosting(codeletName)
howMany = workspaceFormulas.howManyToPost(codeletName)
#if codeletName == 'bottom-up-bond-scout':
# print 'post --> %f:%d' % (probability,howMany)
if self.speedUpBonds:
if 'bond' in codeletName or 'group' in codeletName:
howMany *= 3
urgency = 3
if codeletName == 'breaker':
urgency = 1
@ -121,7 +113,7 @@ class CodeRack(object):
else:
newCodelet.arguments = oldCodelet.arguments
newCodelet.pressure = oldCodelet.pressure
self.tryRun(newCodelet)
self.post(newCodelet)
# pylint: disable=too-many-arguments
def proposeRule(self, facet, description, category, relation, oldCodelet):
@ -209,7 +201,7 @@ class CodeRack(object):
return None
urgencies = []
for codelet in self.codelets:
urgency = ((coderack.codeletsRun - codelet.timeStamp) *
urgency = ((self.codeletsRun - codelet.timeStamp) *
(7.5 - codelet.urgency))
urgencies += [urgency]
threshold = random.random() * sum(urgencies)
@ -226,17 +218,14 @@ class CodeRack(object):
codelet = Codelet(name, 1, self.codeletsRun)
self.post(codelet)
def tryRun(self, newCodelet):
if self.removeTerracedScan:
self.run(newCodelet)
else:
self.post(newCodelet)
def getCodeletMethods(self):
self.methods = {}
for name in dir(codeletMethods):
method = getattr(codeletMethods, name)
if getattr(method, 'is_codelet_method', False):
self.methods[method.codelet_name] = method
def getCodeletmethods(self):
import codeletMethods
self.codeletMethodsDir = dir(codeletMethods)
knownCodeletNames = (
assert set(self.methods.keys()) == set([
'breaker',
'bottom-up-description-scout',
'top-down-description-scout',
@ -261,19 +250,11 @@ class CodeRack(object):
'important-object-correspondence-scout',
'correspondence-strength-tester',
'correspondence-builder',
)
self.methods = {}
for codeletName in knownCodeletNames:
methodName = re.sub('[ -]', '_', codeletName)
if methodName not in self.codeletMethodsDir:
raise NotImplementedError(
'Cannot find %s in codeletMethods' % methodName)
method = getattr(codeletMethods, methodName)
self.methods[methodName] = method
])
def chooseAndRunCodelet(self):
if not len(coderack.codelets):
coderack.postInitialCodelets()
if not len(self.codelets):
self.postInitialCodelets()
codelet = self.chooseCodeletToRun()
if codelet:
self.run(codelet)
@ -282,21 +263,6 @@ class CodeRack(object):
if not self.codelets:
return None
#logging.info('temperature: %f', formulas.Temperature)
#logging.info('actualTemperature: %f', formulas.actualTemperature)
#logging.info('Slipnet:')
#for node in slipnet.slipnodes:
# logging.info("\tnode %s, activation: %d, buffer: %d, depth: %s",
# node.get_name(), node.activation, node.buffer,
# node.conceptualDepth)
#logging.info('Coderack:')
#for codelet in self.codelets:
# logging.info('\t%s, %d', codelet.name, codelet.urgency)
#from workspace import workspace
#workspace.initial.log("Initial: ")
#workspace.target.log("Target: ")
scale = (100.0 - formulas.Temperature + 10.0) / 15.0
urgsum = sum(codelet.urgency ** scale for codelet in self.codelets)
threshold = random.random() * urgsum
@ -314,33 +280,12 @@ class CodeRack(object):
return chosen
def run(self, codelet):
methodName = re.sub('[ -]', '_', codelet.name)
methodName = codelet.name
self.codeletsRun += 1
self.runCodelets[methodName] = self.runCodelets.get(methodName, 0) + 1
#if self.codeletsRun > 2000:
#import sys
#print "running too many codelets"
#for name,count in self.postings.iteritems():
#print '%d:%s' % (count,name)
#raise ValueError
#else:
# print 'running %d' % self.codeletsRun
if not self.codeletMethodsDir:
self.getCodeletmethods()
#if not self.codeletMethodsDir:
method = self.methods[methodName]
if not method:
raise ValueError('Found %s in codeletMethods, but cannot get it',
methodName)
if not callable(method):
raise RuntimeError('Cannot call %s()' % methodName)
args, _varargs, _varkw, _defaults = inspect.getargspec(method)
try:
if 'codelet' in args:
method(codelet)
else:
method()
method(self, codelet)
except AssertionError:
pass