def test_raise_exception_with_non_boolean_output(self): """Replaces True output for number 10, then it has a non boolean output, should raise NotImplementedWithMLYet""" function = f.only_boolean r = Rules() r.add(a=True, output=10) r.add(a=True, output=10) r.add(b=True, output=False) with self.assertRaises(NotImplementedWithMLYet): r.solve(function)
def test_me(self): #TODO: make it right should return not (idx1 != x and idx1 != y) #r = Rules(different1=Code('idx1 != x'), # different2=Code('idx2 != y'), output=False) idx = Code() idy = Code() x = Code() y = Code() r = Rules(different1=idx == x, different2=idy == y, output=True) r.solve(me, self)
def test_valid_indexes(self): idx1 = Code() idx2 = Code() max_idx1 = Code() max_idx2 = Code() # TODO: ERROR when output is not present. FIX r = Rules(more_than1=idx1 >= 0, less_than1=idx1 < max_idx1, more_than2=idx2 >= 0, less_than2=idx2 < max_idx2, output=True) r.solve(valid_indexes, self)
def test_2_integer_inputs_easy(self): """ The hypothesis should simplify to single interval of one of the 2 variables. """ function = f.two_inputs_bit_more_complex code_solution_1 = [ "def {}(a, b):".format(function.__name__), " return (a>=0.5 and a<=2.5)" ] code_solution_2 = [ "def {}(a, b):".format(function.__name__), " return (b>=0.5 and b<=2.5)" ] r = Rules() r.add(a=0, b=0, output=0) r.add(a=1, b=1, output=1) r.add(a=2, b=2, output=1) r.add(a=3, b=3, output=0) solution = r.solve(function) try: self.assertEqual(solution.implementation, code_solution_1) except AssertionError: self.assertEqual(solution.implementation, code_solution_2)
def test_sklearn_iris_data_set(self): """ Should generate a hypothesis for the sklearn iris data-set with low test error. """ iris = datasets.load_iris() x = iris.data y = iris.target data_frame = pd.DataFrame(x, columns=['x1', 'x2', 'x3', 'x4']) # Make binary and add to df data_frame[KEYWORDS[OUTPUT]] = [int(bool(e)) for e in y] # TODO: solve for the other classes: How to admit less than perfect solutions? introduce max_error, or timeout? #data_frame[KEYWORDS[OUTPUT]] = [int(abs(e-1)) for e in y] #data_frame[KEYWORDS[OUTPUT]] = [int(bool(abs(e-2))) for e in y] function = f.solve_iris code_solution_1 = [ "def {}(x1, x2, x3, x4):".format(function.__name__), " return x3 >= 2.45" ] r = Rules(data_frame) solution = r.solve(function) self.assertEqual(solution.implementation, code_solution_1)
def test_complex_function2(self): """ Test a 10 input function. """ function = f.complex_2 code = ['def {}(a, b, c, d, e, f, g, h, i, j):'.format(function.__name__), ' return a and b and c and d and e and f and g and h and i and j'] # Random rules. r = Rules() kwargs = {'a': True, 'b': True, 'c': True, 'd': True, 'e': True, 'f': True, 'g': True, 'h': True, 'i': True, 'j': True} true_kwargs = copy.copy(kwargs) true_kwargs['output'] = True r.add(**true_kwargs) r.add(**true_kwargs) # 1 outlier, the model should learn to ignore it. false_kwargs = copy.copy(kwargs) false_kwargs['output'] = False r.add(**false_kwargs) solution = r.solve(function, self) self.assertEqual(solution.implementation, code)
def test_2_integer_inputs_bit_more_complex(self): """ Here the QM simplification is tested. There are 2 right solutions. """ function = f.two_inputs_bit_more_complex code_solution_1 = [ "def {}(a, b):".format(function.__name__), " return (b>=2.5 and b<=5.5) or a<=1.5" ] code_solution_2 = [ "def {}(a, b):".format(function.__name__), " return (b>=2.5 and b<=5.5) or b<=1.5" ] r = Rules() r.add(a=4, b=6, output=0) r.add(a=5, b=5, output=1) r.add(a=6, b=4, output=1) r.add(a=3, b=3, output=1) r.add(a=2, b=2, output=0) r.add(a=1, b=1, output=1) solution = r.solve(function) # Tries 2 valid solutions. try: self.assertEqual(solution.implementation, code_solution_1) except AssertionError: self.assertEqual(solution.implementation, code_solution_2)
def test_double_input_will_not_have_effect(self): """Even though the input is fed twice the result is the same.""" solution = ['def {}(a):'.format(f.double_input.__name__), ' return a'] r = Rules(a=True, output=True) r.add(a=True, output=True) s = r.solve(f.double_input) self.assertEqual(s.implementation, solution)
def test_living_rule(self): """ 1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation. 2. Any live cell with more than three live neighbours dies, as if by overcrowding. 3. Any live cell with two or three live neighbours lives on to the next generation. 4. Any dead cell with exactly three live neighbours becomes a live cell. """ r = Rules(rule1=Code(code_str='sum(neighbors) < 2'), output=False) r.add(rule2=Code('sum(neighbors) > 3'), output=False) r.add(alive=True, rule3=Code(code_str='sum(neighbors) == 2'), output=True) r.add(alive=True, rule4=Code(code_str='sum(neighbors) == 3'), output=True) r.add(alive=False, rule5=Code(code_str='sum(neighbors) == 3'), output=True) r.solve(is_alive, self)
def test_and(self): """ Test the and function when the input has 1 outlier out of 3 samples. """ function = f.and_f code = ['def {}(a, b):'.format(function.__name__), ' return a and b'] # 2 correct samples r = Rules(a=True, b=True, output=True) r.add(a=True, b=True, output=True) # 1 outlier, the model should learn to ignore it. r.add(a=True, b=True, output=False) solution = r.solve(function, self) self.assertEqual(solution.implementation, code)
def test_identity(self): """ Test the identity function when the input 'a' has 1 outlier out of 3 samples. """ code = ['def {}(a):'.format(f.identity.__name__), ' return a'] # 2 correct samples. r = Rules(a=True, output=True) r.add(a=True, output=True) # 1 outlier, the model should learn to ignore it. r.add(a=True, output=False) solution = r.solve(f.identity, self) self.assertEqual(solution.implementation, code)
def test_simple_integer_input(self): """ Simple integer input """ function = f.simple code = ["def {}(a):".format(function.__name__), " return a>=2.5"] r = Rules() r.add(a=0, output=0) r.add(a=1, output=0) r.add(a=2, output=0) r.add(a=3, output=1) solution = r.solve(function) self.assertEqual(solution.implementation, code)
def test_complex_function(self): """ Test a bit more complex function """ function = f.complex code = ['def {}(a, b, c, d):'.format(function.__name__), ' return a and b and c or d'] # 3 correct samples. r = Rules(a=True, b=True, c=True, output=True) r.add(d=True, output=True) r.add(d=True, output=True) # 1 outlier, the model should learn to ignore it. r.add(d=True, output=False) solution = r.solve(function, self) self.assertEqual(solution.implementation, code)
def test_false_and(self): """Has the same combination twice with a output=False while having another one with a contradiction """ function = f.false_and code = ['def {}(a, b):'.format(function.__name__), '', ' return False'] r = Rules() # 2 correct samples. r.add(a=True, b=True, output=False) r.add(a=True, b=True, output=False) # 1 outlier, the model should learn to ignore it. r.add(a=True, b=True, output=True) solution = r.solve(function) self.assertEqual(solution.implementation, code)
def test_many_integer_inputs_easy(self): """ The hypothesis should simplify to single interval of one of the 2 variables. """ function = f.many_inputs_bit_more_complex code_abstract_solution = [ "def {}(a, b, c, d, e, f):".format(function.__name__), " return ({var}>=0.5 and {var}<=2.5)" ] r = Rules() r.add(a=0, b=0, c=0, d=0, e=0, f=0, output=0) r.add(a=1, b=1, c=1, d=1, e=1, f=1, output=1) r.add(a=2, b=2, c=2, d=2, e=2, f=2, output=1) r.add(a=3, b=3, c=3, d=3, e=3, f=3, output=0) solution = r.solve(function) variables = [ 'a', 'b', 'c', 'd', 'e', 'f', ] for var in variables: try: code = [ code_abstract_solution[0], code_abstract_solution[1].format(var=var) ] self.assertEqual(solution.implementation, code) return # happy ending except AssertionError: pass # still nothing raise Exception #
def test_simple2_integer_input(self): """ Bit more complex Simple integer input """ function = f.bit_more_complex code = [ "def {}(a):".format(function.__name__), " return (a>=0.5 and a<=2.5)" ] r = Rules() r.add(a=0, output=0) r.add(a=1, output=1) r.add(a=2, output=1) r.add(a=3, output=0) solution = r.solve(function) self.assertEqual(solution.implementation, code)
def test_2_integer_inputs_variant(self): """ Variant of the test above. It is no longer a square. """ function = f.two_inputs_bit_more_complex code = [ "def {}(a, b):".format(function.__name__), " return (b>=1.0 and b<=2.0) and ((a>=1.5 and a<=2.0) or a<=0.5)" ] r = Rules() r.add(a=1, b=0, output=0) r.add(a=0, b=1, output=1) r.add(a=1, b=1, output=0) r.add(a=2, b=2, output=1) r.add(a=3, b=2, output=0) r.add(a=2, b=3, output=0) solution = r.solve(function) self.assertEqual(solution.implementation, code)
def test_2_integer_inputs(self): """ The hypothesis that solves this problem is a perfect square on the plane with coordinates (a, b) """ function = f.two_inputs_bit_more_complex code = [ "def {}(a, b):".format(function.__name__), " return (a>=1.0 and a<=2.0) and (b>=1.0 and b<=2.0)" ] r = Rules() r.add(a=1, b=0, output=0) r.add(a=0, b=1, output=0) r.add(a=1, b=1, output=1) r.add(a=2, b=2, output=1) r.add(a=3, b=2, output=0) r.add(a=2, b=3, output=0) solution = r.solve(function) self.assertEqual(solution.implementation, code)
def test_not_identity(self): """ Test the not-identity function when the input 'a' has 4 outliers out of 9 samples. """ function = f.not_identity code = ['def {}(a):'.format(function.__name__), ' return not a'] # Correct samples r = Rules(a=False, output=True) r.add(a=False, output=True) r.add(a=False, output=True) r.add(a=False, output=True) r.add(a=False, output=True) # Outliers r.add(a=False, output=False) r.add(a=False, output=False) r.add(a=False, output=False) r.add(a=False, output=False) solution = r.solve(function, self) self.assertEqual(solution.implementation, code)
""" 1. Set rules of your function. 2. Run r.solve(callable) where callable is a function with the decorator=@solve(). See examples below: """ @s.solve() def and_function(a, b): pass # A simple and function. r = Rules(a=True, b=True, output=True) r.solve(and_function) @s.solve() def if_function(a, b): pass # A function with an if statement. r = Rules(a=False, b=True, output=1) # non-boolean output r.add(a=True, b=False, output=0) # non-boolean output r.solve(if_function) @s.solve() def recursive(a):