def test_multiplier_interval(self): c1 = Cell(content=Supported(Interval(3, 4))) c2 = Cell(content=Supported(Interval(5, 6))) c3 = Cell() multiplier(c1, c2, c3) scheduler.run() self.assertEqual(c3.content, Supported(Interval(15, 24)))
def fall_duration_helper(): g = Cell('g') one_half = Cell('one half') t_to_2 = Cell('t^2') g_times_t_to_2 = Cell('gt^2') (constant(Interval(9.789, 9.832)))(g) (constant(Interval(0.5, 0.5)))(one_half) quadratic(t, t_to_2) product(g, t_to_2, g_times_t_to_2) product(one_half, g_times_t_to_2, h)
def fall_duration_helper(): g = Cell('g') one_half = Cell('one half') t_to_2 = Cell('t^2') g_times_t_to_2 = Cell('gt^2') (constant(Interval(9.789, 9.832)))(g) (constant(Interval(1 / 2, 1 / 2)))(one_half) squarer(t, t_to_2) multiplier(g, t_to_2, g_times_t_to_2) multiplier(one_half, g_times_t_to_2, h)
def test_merge_supported_none_and_supported_interval(self): nil = Supported(None, {}) sup = Supported(Interval(15, 16), {'this', 'that'}) self.assertEqual( merge(nil, sup), merge(sup, nil), ) self.assertEqual( merge(sup, nil), Supported(Interval(15, 16), {'this', 'that'}) )
def test_merge_flat_interval_and_looser_supported_interval(self): number = Interval(14.5, 16.7) sup = Supported(Interval(3, 18), {'this', 'that'}) self.assertEqual( merge(number, sup), merge(sup, number), ) self.assertEqual( merge(number, sup), Supported(Interval(14.5, 16.7), {}) )
def test_if_merging_contradiction_with_interval_is_contradictory(self): c = Contradiction("foo") n = Interval(5, 10) m1 = merge(c, n) m2 = merge(n, c) self.assertTrue(is_contradictory(m1)) self.assertTrue(is_contradictory(m2))
def test_if_merging_contradiction_with_supported_value_is_contradictory( self): c = Contradiction("foo") n = Supported(Interval(5, 10)) m1 = merge(c, n) m2 = merge(n, c) self.assertTrue(is_contradictory(m1)) self.assertTrue(is_contradictory(m2))
# We now build a sequence of sample dependency tracking systems of # increasing complexity. We start with a relatively simple system # that only tracks and reports the provenance of its data. # # How do we want our provenance system to work? We can make cells # and define networks as usual, but if we add supported values as inputs, # we get supported values as outputs: barometer_height = Cell('barometer height') barometer_shadow = Cell('barometer shadow') building_height = Cell('building height') building_shadow = Cell('building shadow') similar_triangles(barometer_shadow, barometer_height, building_shadow, building_height) building_shadow.add_content(Supported(Interval(54.9, 55.1), ['shadows'])) barometer_height.add_content(Supported(Interval(0.3, 0.32), ['shadows'])) barometer_shadow.add_content(Supported(Interval(0.36, 0.37), ['shadows'])) scheduler.run() print(building_height.content) # Supported(Interval(44.51351351351351, 48.977777777777774), {'shadows'}) # Indeed, our estimate for the height of the building depends on our # measurements of the barometer and the shadow. We can try # dropping the barometer off the roof, but if we do a bad job of # timing its fall, our estimate won’t improve. fall_time = Cell('fall time') fall_duration(fall_time, building_height)
if __name__ == '__main__': scheduler.initialize() # Now the estimation of the building’s height works just fine, barometer_height = Cell('barometer height') barometer_shadow = Cell('barometer shadow') building_height = Cell('building height') building_shadow = Cell('building shadow') similar_triangles(barometer_shadow, barometer_height, building_shadow, building_height) building_shadow.add_content(Interval(54.9, 55.1)) barometer_height.add_content(Interval(0.3, 0.32)) barometer_shadow.add_content(Interval(0.36, 0.37)) scheduler.run() print(building_height.content) # Interval(44.51351351351351, 48.977777777777774) # as does the refinement of that estimate by adding another # measurement. fall_time = Cell('fall time') fall_duration(fall_time, building_height)
def test_supported_doesnt_subsume_one_with_tighter_value_and_tighter_supports(self): sup1 = Supported(Interval(5, 10), {'this', 'that'}) sup2 = Supported(Interval(6, 9), {'this'}) self.assertFalse(sup1.subsumes(sup2))
def test_supported_subsumes_one_with_looser_value_and_looser_supports(self): sup1 = Supported(Interval(6, 9), {'this'}) sup2 = Supported(Interval(5, 10), {'this', 'that'}) self.assertTrue(sup1.subsumes(sup2))
def test_supported_interval_is_not_contradictory(self): sup = Supported(Interval(14, 15), {}) self.assertFalse(is_contradictory(sup))
def test_merge_contradictory_supported_values(self): sup1 = Supported(Interval(3, 6), {}) sup2 = Supported(Interval(7, 9), {}) merged = merge(sup1, sup2) self.assertTrue(is_contradictory(merged))