def test_Template_in_step_repeated_true(): v = Template('v') expr = Step(op.add, 1, 1) test = Step(op.add, v, v) assert are_equal(test, expr) assert are_equal(expr, test) assert are_equal(v.meaning, 1)
def test_Template_in_step(): v = Template('v') expr = Step(op.add, 1, 2) test = Step(op.add, 1, v) assert are_equal(test, expr) assert are_equal(expr, test) assert are_equal(v.meaning, 2)
def test_from_dict_with_dict_params(): a = Step('a') b = Step(dict.get, {'dog': 1, 'cat': 2}, a) assert do_eval(b, a='cat') == 2 p = to_dict(b) e = from_dict(p) assert are_equal(e, b) assert are_equal(b._last_result, e._last_result)
def test_Template_in_step_with_input_partial_operations_invert(): a = Step('a') b = Step('b') v = Template('v') expr = Step(op.add, 1, a+b) test = Step(op.add, 1, v+b) assert are_equal(expr, test) assert are_equal(test, expr) assert are_equal(v.meaning, a)
def test_Template_in_step_with_input(): a = Step('a') b = Step('b') v = Template('v') expr = Step(op.add, a, b) test = Step(op.add, a, v) assert are_equal(expr, test) assert are_equal(test, expr) assert are_equal(v.meaning, b)
def test_Template_in_step_with_input_False(): a = Step('a') b = Step('b') v = Template('v') expr = Step(op.add, 1, a+b) test = Step(op.add, 1, a*v) assert not are_equal(expr, test) assert not are_equal(test, expr) assert are_equal(v.meaning, Tokens.NO_PREVIOUS_RESULT)
def test_basic_equality(): a = Step('a') b = Step('b') c = Step('a') assert not are_equal(a, b) assert are_equal(a, c) assert are_equal(a+b, c+b) assert are_equal(2*(a+b), 2*(c+b))
def test_basic_copy_shallow_and_deep(): b = Step('b') a = Step('a', meta=b) a1 = copy(a) a2 = deepcopy(a) assert are_equal(a, a1) assert are_equal(a, a2) assert a._kwargs['meta'] is a1._kwargs['meta'] assert a._kwargs['meta'] is not a2._kwargs['meta'] assert are_equal(a._kwargs['meta'], a2._kwargs['meta'])
def test_deferred_equality_to_subclass(): class Useless(Step): def __equal__(self, other): return True a = Step("a") b = Useless('b') assert are_equal(a, b) == True assert are_equal(b, a) == True
def test_multiple_templates(): a = Step('a') b = Step('b') v = Template('v') t = Template('t') expr = 1+a+b test = v+a+t assert are_equal(expr, test) assert are_equal(v.meaning, 1) assert are_equal(t.meaning, b)
def test_replace_in_dag(): a = Step('a') b = Step('b') expr1 = 2**a + a*2 + 1 expr2 = replace_in_DAG(deepcopy(expr1), a, b) res1 = do_eval(expr1, a=1, b=2) res2 = do_eval(expr2, a=2, b=1) assert are_equal(res1, res2)
def test_clear_cache_from_errors(): a = Step('a') b = Step('b') expr = 1/b + 1/a do_eval(expr, a=0, b=1) expected_1 = {Tokens.FUNCTION_IDX: op.add, Tokens.CACHE_IDX: TypeError("unsupported operand type(s) for +: 'int' and 'ZeroDivisionError'"), 0: {Tokens.FUNCTION_IDX: op.truediv, Tokens.CACHE_IDX: 1, 0: 1, 1: {Tokens.FUNCTION_IDX: 'b', Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, } }, 1: {Tokens.FUNCTION_IDX: op.truediv, Tokens.CACHE_IDX: ZeroDivisionError('division by zero'), 0: 1, 1: {Tokens.FUNCTION_IDX: 'a', Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, } } } assert are_equal(from_dict(expected_1), from_dict(expected_1)) assert are_equal(expr, from_dict(expected_1)) clean_expr = clear_cache(expr) expected_2 = {Tokens.FUNCTION_IDX: op.add, Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, 0: {Tokens.FUNCTION_IDX: op.truediv, Tokens.CACHE_IDX: 1, 0: 1, 1: {Tokens.FUNCTION_IDX: 'b', Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, } }, 1: {Tokens.FUNCTION_IDX: op.truediv, Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, 0: 1, 1: {Tokens.FUNCTION_IDX: 'a', Tokens.CACHE_IDX: Tokens.NO_PREVIOUS_RESULT, } } } assert are_equal(clean_expr, from_dict(expected_2))
def test_pattern_matching(): a = Step('a') b = Step('b') v = Template('v') expr = 2*(a+b)+3*(a+2*b) test = a+v assert not are_equal(expr, test) results = list(match(test, expr)) assert len(results)==2 assert are_equal(results[0][Tokens.FUNCTION_IDX][0], a+b) assert are_equal(results[0][Tokens.FUNCTION_IDX][1], 2*(a+b)) assert are_equal(results[0][Tokens.FUNCTION_IDX][2], 1) assert are_equal(results[0]['v'], b) assert are_equal(results[1][Tokens.FUNCTION_IDX][0], a+2*b) assert are_equal(results[1][Tokens.FUNCTION_IDX][1], 3*(a+2*b)) assert are_equal(results[1][Tokens.FUNCTION_IDX][2], 1) assert are_equal(results[1]['v'], 2*b)
def test_resect_part_of_the_DAG(a, b, c, d): r = a*d + b*c r2 = do_eval(r, a=1, c=3, d=4) r3 = 4+b*3 assert are_equal(r2, r3) def _replace_idx(obj, idx, value): obj = list(obj) obj[idx] = value return tuple(obj) assert do_eval(r3, b=1) == 7 clear_cache(r3, force=True) r3._args[1] = b*4 assert do_eval(r3, b=1) == 8
def test_simplify_DAG(): a1 = Step('a') a2 = Step('a') b = Step('b') c = Step('c') d1 = Step('d') d2 = Step('d') expr_1 = Step(d1, a1, b) expr_2 = Step(d2, a2, b) expr_3 = Step(lambda x, y: x*y, x=c, y=expr_2) expr = expr_1/expr_3 old_expr = deepcopy(expr) new_expr = simplify(expr) assert are_equal(new_expr, old_expr) len_old = len({id(subdag) for subdag, *_ in old_expr}) len_new = len({id(subdag) for subdag, *_ in expr}) assert len_old == 11 assert len_new == 7 assert len_old >= len_new
def test_math_interface_hyp(name_a, name_b, value_a, value_b, op_math_function): try: expected = op_math_function(value_a, value_b) except Exception: assume(False) try: is_nan_value = isnan(expected) except OverflowError: is_nan_value = False assume(not is_nan_value) assume(name_a != name_b) a = Step(name_a) b = Step(name_b) value_dict = {name_a: value_a, name_b: value_b} expr_1 = Step(op_math_function, a, b) expr_2 = op_math_function(a, b) assert isinstance(expr_1, Step) assert isinstance(expr_2, Step) assert are_equal(expr_1, expr_2) observed_1 = do_eval(expr_1, **value_dict) observed_2 = do_eval(expr_2, **value_dict) assert isinstance(observed_1, type(expected)) assert isinstance(observed_2, type(expected)) assert observed_1 == expected assert observed_2 == expected value_a_dict = {name_a: value_a} expr_direct = op_math_function(a, value_b) assert isinstance(expr_direct, Step) observed = do_eval(expr_direct, **value_a_dict) assert isinstance(observed, type(expected)) assert observed == expected value_b_dict = {name_b: value_b} expr_inverse = op_math_function(value_a, b) assert isinstance(expr_inverse, Step) observed = do_eval(expr_inverse, **value_b_dict) assert isinstance(observed, type(expected)) assert observed == expected
def test_are_equal_exception_special_case(): e1 = ValueError('a') e2 = ValueError('a') e3 = ValueError('b') assert are_equal(e1, e2) assert not are_equal(e1, e3)
def test_equality_independent_key_ordering(): a1 = Step('a', meta=1, type=int) a2 = Step('a', meta=1, type=int) a3 = Step('a', type=int, meta=1) assert are_equal(a1, a2) assert are_equal(a1, a3)
def test_equality_need_same_keys(): a1 = Step('a', meta=1, type=int) a4 = Step('a', meta=1, type=int, time=0) assert not are_equal(a1, a4)
def test_equality_values(): a1 = Step('a', meta=1, type=int) a2 = Step('a', meta=2, type=float) assert not are_equal(a1, a2)
def test_from_dict(): a = Step('a') b = 2**a + 1 p = to_dict(b) e = from_dict(p) assert are_equal(e, b)
def test_Template_basic(): v = Template('v') assert are_equal(v, 1) assert are_equal(v.meaning, 1) assert repr(v) == "Template(name='v', 1)"
def test_multiple_variables(): a, b, c = variables('a', 'b', 'c', type=int) assert are_equal(a, Step('a', type=int)) assert are_equal(b, Step('b', type=int)) assert are_equal(c, Step('c', type=int))
def test_curry_different_expressions(a, b, c, d): r = a*d + b*c r2 = do_eval(r, a=1, c=3, d=4) r3 = 4+b*3 assert are_equal(r2, r3)