Move temperatureAdjustedFoo into the Temperature class. NFC.

And demagic all the callers of this function. Notice that with this
move, it becomes *harder* for these "getAdjustedFoo" functions to
access other contextual state, such as the state of the coderack
and the state of the workspace. This is a good thing for modularity
but possibly a misfeature in terms of flexibility-re-logic-changes.
This commit is contained in:
Arthur O'Dwyer
2017-04-17 20:33:16 -07:00
parent 99dc05f829
commit ff389bd653
4 changed files with 44 additions and 33 deletions

View File

@ -77,11 +77,12 @@ def __getDescriptors(bondFacet, source, destination):
def __structureVsStructure(structure1, weight1, structure2, weight2): def __structureVsStructure(structure1, weight1, structure2, weight2):
ctx = structure1.ctx ctx = structure1.ctx
temperature = ctx.temperature
structure1.updateStrength() structure1.updateStrength()
structure2.updateStrength() structure2.updateStrength()
weightedStrength1 = formulas.temperatureAdjustedValue(ctx, weightedStrength1 = temperature.getAdjustedValue(
structure1.totalStrength * weight1) structure1.totalStrength * weight1)
weightedStrength2 = formulas.temperatureAdjustedValue(ctx, weightedStrength2 = temperature.getAdjustedValue(
structure2.totalStrength * weight2) structure2.totalStrength * weight2)
rhs = (weightedStrength1 + weightedStrength2) * random.random() rhs = (weightedStrength1 + weightedStrength2) * random.random()
logging.info('%d > %d', weightedStrength1, rhs) logging.info('%d > %d', weightedStrength1, rhs)
@ -114,10 +115,10 @@ def __fightIncompatibles(incompatibles, structure, name,
def __slippability(ctx, conceptMappings): def __slippability(ctx, conceptMappings):
temperature = ctx.temperature
for mapping in conceptMappings: for mapping in conceptMappings:
slippiness = mapping.slippability() / 100.0 slippiness = mapping.slippability() / 100.0
probabilityOfSlippage = formulas.temperatureAdjustedProbability(ctx, probabilityOfSlippage = temperature.getAdjustedProbability(slippiness)
slippiness)
if formulas.coinFlip(probabilityOfSlippage): if formulas.coinFlip(probabilityOfSlippage):
return True return True
return False return False
@ -143,7 +144,7 @@ def breaker(ctx, codelet):
breakObjects += [structure.source.group] breakObjects += [structure.source.group]
# Break all the objects or none of them; this matches the Java # Break all the objects or none of them; this matches the Java
for structure in breakObjects: for structure in breakObjects:
breakProbability = formulas.temperatureAdjustedProbability(ctx, breakProbability = temperature.getAdjustedProbability(
structure.totalStrength / 100.0) structure.totalStrength / 100.0)
if formulas.coinFlip(breakProbability): if formulas.coinFlip(breakProbability):
return return
@ -191,11 +192,12 @@ def top_down_description_scout(ctx, codelet):
@codelet('description-strength-tester') @codelet('description-strength-tester')
def description_strength_tester(ctx, codelet): def description_strength_tester(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
temperature = ctx.temperature
description = codelet.arguments[0] description = codelet.arguments[0]
description.descriptor.buffer = 100.0 description.descriptor.buffer = 100.0
description.updateStrength() description.updateStrength()
strength = description.totalStrength strength = description.totalStrength
probability = formulas.temperatureAdjustedProbability(ctx, strength / 100.0) probability = temperature.getAdjustedProbability(strength / 100.0)
assert formulas.coinFlip(probability) assert formulas.coinFlip(probability)
coderack.newCodelet('description-builder', codelet, strength) coderack.newCodelet('description-builder', codelet, strength)
@ -243,6 +245,7 @@ def bottom_up_bond_scout(ctx, codelet):
def rule_scout(ctx, codelet): def rule_scout(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
slipnet = ctx.slipnet slipnet = ctx.slipnet
temperature = ctx.temperature
workspace = ctx.workspace workspace = ctx.workspace
assert workspace.numberOfUnreplacedObjects() == 0 assert workspace.numberOfUnreplacedObjects() == 0
changedObjects = [o for o in workspace.initial.objects if o.changed] changedObjects = [o for o in workspace.initial.objects if o.changed]
@ -283,7 +286,7 @@ def rule_scout(ctx, codelet):
valueList = [] valueList = []
for node in objectList: for node in objectList:
depth = node.conceptualDepth depth = node.conceptualDepth
value = formulas.temperatureAdjustedValue(ctx, depth) value = temperature.getAdjustedValue(depth)
valueList += [value] valueList += [value]
i = formulas.selectListPosition(valueList) i = formulas.selectListPosition(valueList)
descriptor = objectList[i] descriptor = objectList[i]
@ -297,7 +300,7 @@ def rule_scout(ctx, codelet):
valueList = [] valueList = []
for node in objectList: for node in objectList:
depth = node.conceptualDepth depth = node.conceptualDepth
value = formulas.temperatureAdjustedValue(ctx, depth) value = temperature.getAdjustedValue(depth)
valueList += [value] valueList += [value]
i = formulas.selectListPosition(valueList) i = formulas.selectListPosition(valueList)
relation = objectList[i] relation = objectList[i]
@ -308,9 +311,10 @@ def rule_scout(ctx, codelet):
@codelet('rule-strength-tester') @codelet('rule-strength-tester')
def rule_strength_tester(ctx, codelet): def rule_strength_tester(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
temperature = ctx.temperature
rule = codelet.arguments[0] rule = codelet.arguments[0]
rule.updateStrength() rule.updateStrength()
probability = formulas.temperatureAdjustedProbability(ctx, rule.totalStrength / 100.0) probability = temperature.getAdjustedProbability(rule.totalStrength / 100.0)
if formulas.coinFlip(probability): if formulas.coinFlip(probability):
coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule) coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule)
@ -412,11 +416,12 @@ def top_down_bond_scout__direction(ctx, codelet):
@codelet('bond-strength-tester') @codelet('bond-strength-tester')
def bond_strength_tester(ctx, codelet): def bond_strength_tester(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
temperature = ctx.temperature
bond = codelet.arguments[0] bond = codelet.arguments[0]
__showWhichStringObjectIsFrom(bond) __showWhichStringObjectIsFrom(bond)
bond.updateStrength() bond.updateStrength()
strength = bond.totalStrength strength = bond.totalStrength
probability = formulas.temperatureAdjustedProbability(ctx, strength / 100.0) probability = temperature.getAdjustedProbability(strength / 100.0)
logging.info('bond strength = %d for %s', strength, bond) logging.info('bond strength = %d for %s', strength, bond)
assert formulas.coinFlip(probability) assert formulas.coinFlip(probability)
bond.facet.buffer = 100.0 bond.facet.buffer = 100.0
@ -698,12 +703,13 @@ def group_scout__whole_string(ctx, codelet):
def group_strength_tester(ctx, codelet): def group_strength_tester(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
slipnet = ctx.slipnet slipnet = ctx.slipnet
temperature = ctx.temperature
# update strength value of the group # update strength value of the group
group = codelet.arguments[0] group = codelet.arguments[0]
__showWhichStringObjectIsFrom(group) __showWhichStringObjectIsFrom(group)
group.updateStrength() group.updateStrength()
strength = group.totalStrength strength = group.totalStrength
probability = formulas.temperatureAdjustedProbability(ctx, strength / 100.0) probability = temperature.getAdjustedProbability(strength / 100.0)
if formulas.coinFlip(probability): if formulas.coinFlip(probability):
# it is strong enough - post builder & activate nodes # it is strong enough - post builder & activate nodes
group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0
@ -945,6 +951,7 @@ def important_object_correspondence_scout(ctx, codelet):
@codelet('correspondence-strength-tester') @codelet('correspondence-strength-tester')
def correspondence_strength_tester(ctx, codelet): def correspondence_strength_tester(ctx, codelet):
coderack = ctx.coderack coderack = ctx.coderack
temperature = ctx.temperature
workspace = ctx.workspace workspace = ctx.workspace
correspondence = codelet.arguments[0] correspondence = codelet.arguments[0]
objectFromInitial = correspondence.objectFromInitial objectFromInitial = correspondence.objectFromInitial
@ -956,7 +963,7 @@ def correspondence_strength_tester(ctx, codelet):
objectFromTarget.flipped_version()))) objectFromTarget.flipped_version())))
correspondence.updateStrength() correspondence.updateStrength()
strength = correspondence.totalStrength strength = correspondence.totalStrength
probability = formulas.temperatureAdjustedProbability(ctx, strength / 100.0) probability = temperature.getAdjustedProbability(strength / 100.0)
if formulas.coinFlip(probability): if formulas.coinFlip(probability):
# activate some concepts # activate some concepts
for mapping in correspondence.conceptMappings: for mapping in correspondence.conceptMappings:

View File

@ -32,22 +32,6 @@ def weightedAverage(values):
return total / totalWeights return total / totalWeights
def temperatureAdjustedValue(ctx, value):
return value ** (((100.0 - ctx.temperature.value()) / 30.0) + 0.5)
def temperatureAdjustedProbability(ctx, value):
if value == 0 or value == 0.5 or ctx.temperature.value() == 0:
return value
if value < 0.5:
return 1.0 - temperatureAdjustedProbability(ctx, 1.0 - value)
coldness = 100.0 - ctx.temperature.value()
a = math.sqrt(coldness)
c = (10 - a) / 100
f = (c + 1) * value
return max(f, 0.5)
def coinFlip(chance=0.5): def coinFlip(chance=0.5):
return random.random() < chance return random.random() < chance
@ -61,12 +45,13 @@ def blur(value):
def chooseObjectFromList(objects, attribute): def chooseObjectFromList(objects, attribute):
from context import context as ctx from context import context as ctx
temperature = ctx.temperature
if not objects: if not objects:
return None return None
probabilities = [] probabilities = []
for objekt in objects: for objekt in objects:
value = getattr(objekt, attribute) value = getattr(objekt, attribute)
probability = temperatureAdjustedValue(ctx, value) probability = temperature.getAdjustedValue(value)
logging.info('Object: %s, value: %d, probability: %d', logging.info('Object: %s, value: %d, probability: %d',
objekt, value, probability) objekt, value, probability)
probabilities += [probability] probabilities += [probability]
@ -87,10 +72,11 @@ def chooseRelevantDescriptionByActivation(workspaceObject):
def similarPropertyLinks(slip_node): def similarPropertyLinks(slip_node):
from context import context as ctx from context import context as ctx
temperature = ctx.temperature
result = [] result = []
for slip_link in slip_node.propertyLinks: for slip_link in slip_node.propertyLinks:
association = slip_link.degreeOfAssociation() / 100.0 association = slip_link.degreeOfAssociation() / 100.0
probability = temperatureAdjustedProbability(ctx, association) probability = temperature.getAdjustedProbability(association)
if coinFlip(probability): if coinFlip(probability):
result += [slip_link] result += [slip_link]
return result return result
@ -98,9 +84,10 @@ def similarPropertyLinks(slip_node):
def chooseSlipnodeByConceptualDepth(slip_nodes): def chooseSlipnodeByConceptualDepth(slip_nodes):
from context import context as ctx from context import context as ctx
temperature = ctx.temperature
if not slip_nodes: if not slip_nodes:
return None return None
depths = [temperatureAdjustedValue(ctx, n.conceptualDepth) for n in slip_nodes] depths = [temperature.getAdjustedValue(n.conceptualDepth) for n in slip_nodes]
i = selectListPosition(depths) i = selectListPosition(depths)
return slip_nodes[i] return slip_nodes[i]

View File

@ -100,6 +100,7 @@ class Group(WorkspaceObject):
def singleLetterGroupProbability(self): def singleLetterGroupProbability(self):
slipnet = self.ctx.slipnet slipnet = self.ctx.slipnet
temperature = self.ctx.temperature
numberOfSupporters = self.numberOfLocalSupportingGroups() numberOfSupporters = self.numberOfLocalSupportingGroups()
if not numberOfSupporters: if not numberOfSupporters:
return 0.0 return 0.0
@ -112,7 +113,7 @@ class Group(WorkspaceObject):
support = self.localSupport() / 100.0 support = self.localSupport() / 100.0
activation = slipnet.length.activation / 100.0 activation = slipnet.length.activation / 100.0
supportedActivation = (support * activation) ** exp supportedActivation = (support * activation) ** exp
return formulas.temperatureAdjustedProbability(self.ctx, supportedActivation) return temperature.getAdjustedProbability(supportedActivation)
def flippedVersion(self): def flippedVersion(self):
slipnet = self.ctx.slipnet slipnet = self.ctx.slipnet
@ -140,13 +141,14 @@ class Group(WorkspaceObject):
def lengthDescriptionProbability(self): def lengthDescriptionProbability(self):
slipnet = self.ctx.slipnet slipnet = self.ctx.slipnet
temperature = self.ctx.temperature
length = len(self.objectList) length = len(self.objectList)
if length > 5: if length > 5:
return 0.0 return 0.0
cubedlength = length ** 3 cubedlength = length ** 3
fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0 fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0
probability = 0.5 ** fred probability = 0.5 ** fred
value = formulas.temperatureAdjustedProbability(self.ctx, probability) value = temperature.getAdjustedProbability(probability)
if value < 0.06: if value < 0.06:
value = 0.0 # otherwise 1/20 chance always value = 0.0 # otherwise 1/20 chance always
return value return value

View File

@ -1,3 +1,4 @@
import math
class Temperature(object): class Temperature(object):
def __init__(self): def __init__(self):
@ -27,3 +28,17 @@ class Temperature(object):
def value(self): def value(self):
return 100.0 if self.clamped else self.actual_value return 100.0 if self.clamped else self.actual_value
def getAdjustedValue(self, value):
return value ** (((100.0 - self.value()) / 30.0) + 0.5)
def getAdjustedProbability(self, value):
if value == 0 or value == 0.5 or self.value() == 0:
return value
if value < 0.5:
return 1.0 - self.getAdjustedProbability(1.0 - value)
coldness = 100.0 - self.value()
a = math.sqrt(coldness)
c = (10 - a) / 100
f = (c + 1) * value
return max(f, 0.5)