Cleanup
This commit is contained in:
@@ -34,26 +34,88 @@ class Operators(unittest.TestCase):
|
||||
other=selection.Selector(b.harmony,changed,b.selector.center,{})
|
||||
self.assertNotEqual(b.selector.evaluate(slow).raw.get('prior/source_relation',0),other.evaluate(slow).raw.get('prior/source_relation',0))
|
||||
|
||||
@unittest.skipUnless(__import__('importlib.util',fromlist=['find_spec']).find_spec('z3'),'development-only pinned solver not installed')
|
||||
def test_sparse_integer_intervals_are_exact_and_role_separable(self):
|
||||
from audition.structured_learning import solve
|
||||
rows=[{'role':'acoustic_solo','delta':{'duration/1':F(2,3)},'prior':F(1,2),'case':'independent'},
|
||||
{'role':'electric_solo','delta':{'duration/1_2':F(-1,2)},'prior':F(1,4),'case':'independent'}]
|
||||
result=solve(rows)
|
||||
self.assertEqual(result['weights'],{'acoustic_solo':{'duration/1':-3},'electric_solo':{'duration/1_2':3}})
|
||||
self.assertEqual(result,solve(list(reversed(rows))))
|
||||
impossible=[*rows,{'role':'acoustic_solo','delta':{'duration/1':F(-2,3)},'prior':F(1,2),'case':'opposite'}]
|
||||
self.assertEqual(solve(impossible)['status'],'incompatible_with_current_features_and_bounds')
|
||||
|
||||
def test_full_rollout_uses_the_requested_data_and_role_context(self):
|
||||
import copy
|
||||
from generator import vocabulary
|
||||
from audition.fit_selection import fit
|
||||
resources=copy.deepcopy(vocabulary.current()['data'])
|
||||
resources['roles']['difficulty']['triplet_max_bpm']=123
|
||||
b=builder(('CM7',),count=1)
|
||||
action=operators.Action(F(),F(4),(fixture.note(0,4,'c'),),'tone')
|
||||
def proposed(at,**kwargs):
|
||||
self.assertEqual(vocabulary.current()['role'],'acoustic_solo')
|
||||
self.assertEqual(vocabulary.data('roles')['difficulty']['triplet_max_bpm'],123)
|
||||
return (action,) if at==0 else ()
|
||||
with patch.object(b.operators,'at',side_effect=proposed),contextlib.redirect_stdout(io.StringIO()):
|
||||
result=fit([('synthetic','acoustic_solo',b,(action,))],1,resources=resources)
|
||||
self.assertTrue(result['complete'])
|
||||
|
||||
def test_complete_training_rounds_accumulate_only_compatible_evidence(self):
|
||||
from audition.train_completed import training_context,previous_constraints
|
||||
data=copy.deepcopy(vocabulary.current()['data'])
|
||||
context=training_context(data)
|
||||
data['roles']['roles']['electric_solo']['selection_weights']={'duration/1':7}
|
||||
data['roles']['provenance']='Explicit development trial'
|
||||
self.assertEqual(context,training_context(data))
|
||||
cases={'example':{'role':'electric_solo','source_sha256':'source','target_sha256':'example'}}
|
||||
old={'schema':'complete-candidate-training-1','context':context,'training_dependency':cases,
|
||||
'constraints':[{'case':'example','role':'electric_solo','delta':{'duration/1':'2/3'},'prior':'1/2'}]}
|
||||
row=previous_constraints(old,cases,context)[0]
|
||||
self.assertEqual(row['delta']['duration/1'],F(2,3));self.assertEqual(row['prior'],F(1,2))
|
||||
changed=copy.deepcopy(cases);changed['example']['target_sha256']='different'
|
||||
with self.assertRaises(ValueError):previous_constraints(old,changed,context)
|
||||
data['roles']['roles']['electric_solo']['register_center']+=12
|
||||
with self.assertRaises(ValueError):previous_constraints(old,cases,training_context(data))
|
||||
bad=copy.deepcopy(old);bad['constraints'][0]['delta']={'song/example':1}
|
||||
with self.assertRaises(ValueError):previous_constraints(bad,cases,context)
|
||||
|
||||
def test_coverage_diagnostic_does_not_accept_a_shortened_target_hold(self):
|
||||
from audition.structured_learning import CoverageTrace
|
||||
from generator.solo.construction import State
|
||||
held=fixture.note(0,2,'e')
|
||||
target=operators.Action(F(),F(2),(held,),'tone')
|
||||
trace=CoverageTrace((target,))
|
||||
self.assertFalse(trace.matches((dataclasses.replace(held,end=F(1)),),F(1)))
|
||||
self.assertTrue(trace.matches((held,),F(2)))
|
||||
# A computational cut through an already committed hold is different
|
||||
# from selecting a shorter attack and promising to repair it afterward.
|
||||
s=State(action=target,notes=(held,))
|
||||
trace('frontier',F(1),None,(s,),(s,))
|
||||
self.assertFalse(trace.records)
|
||||
|
||||
@unittest.skipUnless(__import__('importlib.util',fromlist=['find_spec']).find_spec('z3'),'development-only pinned solver not installed')
|
||||
def test_shared_fitter_learns_an_independent_synthetic_decision(self):
|
||||
from audition.fit_selection import fit
|
||||
b=builder(('CM7',),count=1)
|
||||
low=operators.Action(F(),F(4),(fixture.note(0,4,'c',event_id='low'),),'tone')
|
||||
high=operators.Action(F(),F(4),(fixture.note(0,4,'e',event_id='high'),),'tone')
|
||||
b.selector.weights={}
|
||||
with patch.object(b.operators,'at',return_value=(low,high)),contextlib.redirect_stdout(io.StringIO()):
|
||||
with patch.object(b.operators,'at',side_effect=lambda at,**kwargs: (low,high) if at==0 else ()),contextlib.redirect_stdout(io.StringIO()):
|
||||
result=fit([('synthetic','acoustic_solo',b,(high,))],10)
|
||||
self.assertTrue(result['complete'])
|
||||
b.selector.weights=result['weights']['acoustic_solo']
|
||||
self.assertLess(b.selector.evaluate(high).total,b.selector.evaluate(low).total)
|
||||
selection.validate_weights(b.selector.weights)
|
||||
|
||||
@unittest.skipUnless(__import__('importlib.util',fromlist=['find_spec']).find_spec('z3'),'development-only pinned solver not installed')
|
||||
def test_fitting_normalization_covers_pickup_plus_whole_note(self):
|
||||
from audition.fit_selection import fit
|
||||
b=builder(('CM7',),count=2);b.end=F(17,4)
|
||||
low=operators.Action(F(),b.end,(fixture.note(0,F(1,4),'c',event_id='lead'),fixture.note(F(1,4),b.end,'e',event_id='low')),'anticipation')
|
||||
high=dataclasses.replace(low,notes=(low.notes[0],fixture.note(F(1,4),b.end,'g',event_id='high')))
|
||||
b.selector.weights={}
|
||||
with patch.object(b.operators,'at',return_value=(low,high)),contextlib.redirect_stdout(io.StringIO()):
|
||||
with patch.object(b.operators,'at',side_effect=lambda at,**kwargs: (low,high) if at==0 else ()),contextlib.redirect_stdout(io.StringIO()):
|
||||
result=fit([('synthetic','acoustic_solo',b,(high,))],10)
|
||||
self.assertTrue(result['complete'])
|
||||
selection.validate_weights(result['weights']['acoustic_solo'])
|
||||
@@ -135,7 +197,7 @@ class Operators(unittest.TestCase):
|
||||
v=b.selector.evaluate(a)
|
||||
self.assertEqual(v.total,sum(v.contributions.values()))
|
||||
self.assertEqual(v.total,b.selector.cost(a))
|
||||
key='kind/tone';b.selector.weights={key:3}
|
||||
key='duration/'+str(a.end-a.start).replace('/','_');b.selector.weights={key:3}
|
||||
changed=b.selector.evaluate(a)
|
||||
self.assertEqual(changed.total,b.selector.cost(a))
|
||||
self.assertEqual(changed.total-v.total,3*v.raw[key])
|
||||
|
||||
Reference in New Issue
Block a user