예제 #1
0
def check_program(name: str, inputs: list, outputs: list,
                  sig: ProgramSignature, iset: InstructionSet) -> PushState:
    """Returns the PushState for further validation."""
    interpreter = PushInterpreter(iset)
    prog = get_program(name, sig, interpreter)
    assert interpreter.run(prog, inputs) == outputs
    return interpreter.state
예제 #2
0
def test_program_relu_2(interpreter: PushInterpreter):
    prog = load_program("relu_via_if")
    result = interpreter.run(prog, [-5], ["float"])
    assert result == [0.0]

    result = interpreter.run(prog, [5.6], ["float"])
    assert result == [5.6]
예제 #3
0
def test_program_point_dist(point_instr_set):
    interpreter = PushInterpreter(point_instr_set)
    prog = load_program("point_distance", interpreter)
    interpreter.run(prog, [1.0, 3.0, 3.0, 3.0], ["float"])
    assert list(interpreter.state["float"]) == [2.0]

    interpreter.run(prog, [3.0, 2.5, 3.0, -3.0], ["float"])
    assert list(interpreter.state["float"]) == [5.5]
예제 #4
0
def test_program_relu_2():
    interpreter = PushInterpreter(InstructionSet(register_core=True).register_n_inputs(1))
    prog = load_program("relu_via_if", interpreter)
    result = interpreter.run(prog, [-5], ["float"])
    assert result == [0.0]

    result = interpreter.run(prog, [5.6], ["float"])
    assert result == [5.6]
예제 #5
0
def test_interpreter_constraints(push_config: PushConfig, instr_set: InstructionSet):
    name = "infinite_growth"
    sig = ProgramSignature(arity=0, output_stacks=["int"], push_config=push_config)
    interpreter = PushInterpreter(instr_set)
    cb = load_code(name, interpreter)
    program = Program(code=cb, signature=sig)
    output = interpreter.run(program, [0], print_trace=True)
    assert output[0] == int(push_config.numeric_magnitude_limit)
    assert interpreter.status == PushInterpreterStatus.step_limit_exceeded
예제 #6
0
class TestPushInterpreterMethods(unittest.TestCase):
    def setUp(self):
        self.i = PushInterpreter()

    def test_reset(self):
        self.i.reset()

    def test_eval_atom_literal(self):
        self.i.eval_atom(5)
        self.assertEqual(self.i.state['_integer'][0], 5)

    def test_eval_atom_list(self):
        self.i.eval_atom([1, 2, 3, 4, 5])
        self.assertEqual(len(self.i.state['_exec']), 5)

    def test_eval_push(self):
        self.i.state['_exec'].push([1, 2, [3, 4], 5])
        self.i.eval_push()
        self.assertEqual(len(self.i.state['_integer']), 5)
        self.assertEqual(len(self.i.state['_exec']), 0)

    def test_run(self):
        outputs = self.i.run([7, 'hello'],
                             inputs=["a", "b", "c"],
                             output_types=['_string'])
        self.assertEqual(outputs, ['hello'])
예제 #7
0
def error_func(program):
    errors = []
    for x in range(10):
        # Create the push interpreter
        interpreter = PushInterpreter()
        y_hat = interpreter.run(program, [x], ['_integer'])[0]
        # Get output
        if y_hat is None:
            errors.append(1e5)
        else:
            # compare to target output
            y_target = target_function(x)
            # calculate error
            errors.append(abs(y_hat - y_target))
    return errors
예제 #8
0
def iris_error_func(program):
    error_vec = []
    for i in range(X_train.shape[0]):
        interpreter = PushInterpreter()
        outputs = interpreter.run(program, X_train[i],
                                  ['_float', '_float', '_float'])
        not_none = [x for x in outputs if x is not None]
        if len(not_none) == 0:
            error_vec.append(1000000)
        else:
            y_hat = outputs.index(max(not_none))
            if y_hat == y_train[i]:
                error_vec.append(0)
            else:
                error_vec.append(1)
    return error_vec
예제 #9
0
def error_func(program):
    errors = []
    for x in range(10):
        # Create the push interpreter and run program
        interpreter = PushInterpreter()
        y_hat = interpreter.run(program, inputs=[x],
                                output_types=['_integer'])[0]
        # Get output
        if y_hat is not None:
            # compare to target output
            target_int = target_function(x)
            # calculate error
            errors.append((y_hat - target_int)**2)
        else:
            errors.append(1e5)
    return errors
def error_function(program):
    errors = []
    for case in cases:
        interpreter = PushInterpreter()
        outputs = interpreter.run(program, case, ['_boolean', '_boolean', '_boolean'])
        targets = two_bit_control_shift(case)
        e = 0

        if outputs[0] is None:
            e += 1e4
        elif outputs[0] != targets[0]:
            e += 1

        if outputs[1] is None:
            e += 1e4
        elif outputs[1] != targets[1]:
            e += 1

        if outputs[2] is None:
            e += 1e4
        elif outputs[2] != targets[2]:
            e += 1

        errors.append(e)
    return errors
예제 #11
0
 def __init__(self,
              interpreter: PushInterpreter = "default",
              penalty: float = 1e6):
     self.penalty = penalty
     if interpreter == "default":
         self.interpreter = PushInterpreter()
     else:
         self.interpreter = interpreter
예제 #12
0
    def __init__(self,
                 spawner: GeneSpawner,
                 search: str = "GA",
                 selector: Union[sl.Selector, str] = "lexicase",
                 variation_strategy: Union[vr.VariationStrategy, dict,
                                           str] = "umad",
                 population_size: int = 300,
                 max_generations: int = 100,
                 initial_genome_size: Tuple[int, int] = (20, 100),
                 simplification_steps: int = 2000,
                 last_str_from_stdout: bool = False,
                 interpreter: PushInterpreter = "default",
                 parallelism: Union[int, bool] = False,
                 push_config: PushConfig = "default",
                 verbose: int = 0,
                 **kwargs):
        self._search_name = search
        self.spawner = spawner
        self.selector = selector
        self.variation_strategy = variation_strategy
        self.population_size = population_size
        self.max_generations = max_generations
        self.initial_genome_size = initial_genome_size
        self.simplification_steps = simplification_steps
        self.last_str_from_stdout = last_str_from_stdout
        self.parallelism = parallelism
        self.verbose = verbose
        self.ext = kwargs
        set_verbosity(self.verbose)

        # Initialize attributes that will be set later.
        self.evaluator = None
        self.signature = None
        self.search = None
        self.solution = None

        if interpreter == "default":
            self.interpreter = PushInterpreter()
        else:
            self.interpreter = interpreter

        if push_config == "default":
            self.push_config = PushConfig()
        else:
            self.push_config = push_config
예제 #13
0
파일: odd.py 프로젝트: lacava/pyshgp
def odd_error_func(program, debug=False):
    errors = []
    for i in range(10):
        # Create the push interpreter
        interpreter = PushInterpreter()
        interpreter.state['_integer'].push(i)
        # Run program
        y_hat = interpreter.run(program, [i], ['_boolean'], debug)[0]
        # Get output
        if y_hat is None:
            errors.append(1e5)
        else:
            # compare to target output
            y = bool(i % 2)
            if y_hat == y:
                errors.append(0)
            else:
                errors.append(1)
    return errors
예제 #14
0
파일: count_odds.py 프로젝트: lacava/pyshgp
def error_function(program, debug=False):
    errors = []
    for case in training_set:
        interpreter = PushInterpreter()
        result = interpreter.run(program, [case[0]], ['_integer'], debug)[0]
        if result is None:
            errors.append(1e5)
        else:
            errors.append((case[1] - result)**2)
    return errors
예제 #15
0
 def test_point_distance(self, push_config: PushConfig,
                         point_instr_set: InstructionSet):
     name = "point_distance"
     sig = ProgramSignature(arity=4,
                            output_stacks=["float"],
                            push_config=push_config)
     interpreter = PushInterpreter(point_instr_set)
     prog = get_program(name, sig, interpreter)
     assert prog.pretty_str(
     ) == "(input_0 input_1 point_from_floats input_2 input_3 point_from_floats point_dist)"
예제 #16
0
def error_function(program):
    errors = []
    for case in cases:
        interpreter = PushInterpreter()
        output = interpreter.run(program, [case], ['_vector_boolean'])[0]
        if output is None:
            errors.append(1e5)
        else:
            target = binary_decrement(case)
            errors.append(levenshtein_distance(output, target))
    return errors
예제 #17
0
def error_function(program, debug=False):
    errors = []
    for case in training_set:
        interpreter = PushInterpreter()
        result = interpreter.run(program, [case[0]], ['_vector_integer'],
                                 debug)[0]
        if result is None:
            errors.append(1e5)
        else:
            errors.append(levenshtein_distance(case[1], result))
    return errors
예제 #18
0
def string_error_func(program):
    inputs = [
        "abcde", "", "E", "Hi", "Tom", "leprechaun", "zoomzoomzoom",
        "qwertyuiopasd", "GallopTrotCanter", "Quinona", "_abc"
    ]
    errors = []

    for inpt in inputs:
        # Create the push interpreter
        interpreter = PushInterpreter()
        y_hat = interpreter.run(program, [inpt], ['_string'])[0]
        if y_hat is None:
            errors.append(1e5)
        else:
            # compare to target output
            target_output = inpt[:-2] + inpt[:-2]
            errors.append(
                string_difference(y_hat, target_output) +
                string_char_counts_difference(y_hat, target_output))
    return errors
예제 #19
0
파일: smallest.py 프로젝트: lacava/pyshgp
def error_function(program, debug=False):
    errors = []
    for case in training_set:
        interpreter = PushInterpreter()
        interpreter.run(program, case[0], [], debug)
        result = interpreter.state.stdout
        if result is None:
            errors.append(1e5)
        else:
            errors.append(int(result != case[1]))
    return errors
예제 #20
0
def test_instructions(core_type_lib, push_config):
    debug = False
    interp = PushInterpreter()
    iset = interp.instruction_set
    for spec in SPECS:
        in_state = PushState.from_dict(spec["in"], core_type_lib, push_config)
        ex_state = PushState.from_dict(spec["ex"], core_type_lib, push_config)
        interp.state = in_state
        instruction_name = spec["instr"]
        if debug:
            print(instruction_name,)
            in_state.pretty_print()
            print("---")
            ex_state.pretty_print()
            print("---")
        interp.evaluate_atom(iset[instruction_name].meta(), push_config)
        ac_state = interp.state
        if debug:
            ac_state.pretty_print()
            print()
        assert ex_state == ac_state
예제 #21
0
def test_program_fibonacci():
    interpreter = PushInterpreter(InstructionSet(register_core=True).register_n_inputs(1))
    prog = load_program("fibonacci", interpreter)
    interpreter.run(prog, [5], [])
    assert list(interpreter.state["int"]) == [1, 1, 2, 3, 5]

    interpreter.run(prog, [1], [])
    assert list(interpreter.state["int"]) == [1]

    interpreter.run(prog, [-3], [])
    assert list(interpreter.state["int"]) == []
예제 #22
0
def error_function(program, debug=False):
    errors = []
    for case in cases:
        interpreter = PushInterpreter()
        output = interpreter.run(program, [case], ['_vector_boolean'], debug)[0]
        target = invert_bitstring(case)
        if output is None:
            errors.append(1e5)
        if not len(output) == len(target):
            errors.append(1e4)
        else:
            errors.append(levenshtein_distance(output, target))
    return errors
예제 #23
0
def error_function(program, debug=False):
    errors = []
    for case in training_set:
        interpreter = PushInterpreter()
        result = interpreter.run(program, case[0], ['_vector_integer'],
                                 debug)[0]
        if result is None:
            errors.append(1e5)
        else:
            e = []
            for i in range(min(len(result), len(case[1]))):
                e.append(abs(result[i] - case[1][i]))
            e.append(abs(len(result) - len(case[1])) * 100)
            errors.append(sum(e))
예제 #24
0
파일: decrement.py 프로젝트: lacava/pyshgp
def error_function(program):
    errors = []
    for case in cases:
        interpreter = PushInterpreter()
        output = interpreter.run(program, [case], ['_vector_integer'])[0]
        target = [x - 1 for x in case]
        if output is None:
            errors.append(1e5)
        elif len(output) != len(target):
            errors.append(1e4)
        else:
            rmse = np.linalg.norm(np.array(output) -
                                  np.array(target)) / np.sqrt(len(output))
            errors.append(rmse)
    return errors
예제 #25
0
def test_program_fibonacci(interpreter: PushInterpreter):
    prog = load_program("fibonacci")
    interpreter.run(prog, [5], [])
    assert list(interpreter.state["int"]) == [1, 1, 2, 3, 5]

    interpreter.run(prog, [1], [])
    assert list(interpreter.state["int"]) == [1]

    interpreter.run(prog, [-3], [])
    assert list(interpreter.state["int"]) == []
예제 #26
0
def test_program_rswn():
    interpreter = PushInterpreter(InstructionSet(register_core=True).register_n_inputs(1))
    prog = load_program("replace_space_with_newline", interpreter)
    interpreter.run(prog, ["hello world"], [])
    assert list(interpreter.state["int"]) == [10]
    assert interpreter.state.stdout == "hello\nworld"

    interpreter.run(prog, ["nospace"], [])
    assert list(interpreter.state["int"]) == [7]
    assert interpreter.state.stdout == "nospace"

    interpreter.run(prog, ["   "], [])
    assert list(interpreter.state["int"]) == [0]
    assert interpreter.state.stdout == "\n\n\n"
예제 #27
0
def test_inputs(core_type_lib, push_config):
    interp = PushInterpreter()

    in_state = PushState.from_dict({"inputs": [7, "x"], "int": []}, core_type_lib, push_config)
    ex_state = PushState.from_dict({"inputs": [7, "x"], "int": [7]}, core_type_lib, push_config)
    interp.state = in_state
    interp.evaluate_atom(Input(input_index=0), push_config)
    ac_state = interp.state
    assert ex_state == ac_state
    assert len(in_state.inputs) == 2

    in_state = PushState.from_dict({"inputs": [7, "x"], "str": []}, core_type_lib, push_config)
    ex_state = PushState.from_dict({"inputs": [7, "x"], "str": ["x"]}, core_type_lib, push_config)
    interp.state = in_state
    interp.evaluate_atom(Input(input_index=1), push_config)
    ac_state = interp.state
    assert ex_state == ac_state
    assert len(in_state.inputs) == 2
예제 #28
0
 def setUp(self):
     self.i = PushInterpreter()
     self.d = {
         '_auxiliary': [],
         '_boolean': [],
         '_char': [],
         '_code': [],
         '_exec': [],
         '_float': [],
         '_input': ['a', 'b', 'c'],
         '_integer': [],
         '_string': [],
         '_vector_boolean': [],
         '_vector_float': [],
         '_vector_integer': [],
         '_vector_string': []
     }
     self.i.state.from_dict(self.d)
예제 #29
0
def test_program_rswn(interpreter: PushInterpreter):
    prog = load_program("replace_space_with_newline")
    interpreter.run(prog, ["hello world"], [])
    assert list(interpreter.state["int"]) == [10]
    assert interpreter.state.stdout == "hello\nworld"

    interpreter.run(prog, ["nospace"], [])
    assert list(interpreter.state["int"]) == [7]
    assert interpreter.state.stdout == "nospace"

    interpreter.run(prog, ["   "], [])
    assert list(interpreter.state["int"]) == [0]
    assert interpreter.state.stdout == "\n\n\n"
예제 #30
0
파일: full_adder.py 프로젝트: lacava/pyshgp
def error_function(program):
    errors = []
    for case in cases:
        interpreter = PushInterpreter()
        output = interpreter.run(program, case, ['_boolean', '_boolean'])
        targets = full_adder(case)
        e = 0

        if output[0] is None:
            e += 1000
        elif output[0] != targets[0]:
            e += 1

        if output[1] is None:
            e += 1000
        elif output[1] != targets[1]:
            e += 1

        errors.append(e)
    return errors
예제 #31
0
def test_estimator_with_custom_types(point_cls, point_instr_set):
    X = np.arange(-1.0, 1.0, 0.05).reshape(-1, 4)
    y = [[point_distance(point_cls(x[0], x[1]), point_cls(x[2], x[3]))]
         for x in X]

    spawner = GeneSpawner(n_inputs=1,
                          instruction_set=point_instr_set,
                          literals=[],
                          erc_generators=[])

    est = PushEstimator(
        spawner=spawner,
        population_size=30,
        max_generations=3,
        simplification_steps=2,
        interpreter=PushInterpreter(point_instr_set),
    )
    est.fit(X, y)

    assert isinstance(est.solution, Individual)
    assert len(est.solution.program.code) > 0
def test_genome_point_dist(point_instr_set):
    check_translation("point_distance", PushInterpreter(point_instr_set))
예제 #33
0
class PushEstimator:
    """Simple estimator that synthesizes Push programs.

    Parameters
    ----------
    spawner : Union[GeneSpawner, str], optional
        The GeneSpawner to use when producing Genomes during initialization and
        variation. Default is all core instructions, no literals, and no ERC Generators.
    search : Union[SearchAlgorithm, str], optional
        The search algorithm, or its abbreviation, to use to when synthesizing
        Push programs.
    selector : Union[Selector, str], optional
        The selector, or name of selector, to use when selecting parents.
        The default is lexicase selection.
    variation_strategy : Union[VariationStrategy, dict, str]
        A VariationStrategy describing a collection of VariationOperators and how
        frequently to use them. If a dict is supplied, keys should be operator
        names and values should be the probability distribution. If a string is
        provided, the VariationOperators with that name will always be used.
        Default is ``"umad""``.
    population_size : int, optional
        The number of individuals hold in the population each generation. Default
        is 300.
    max_generations : int, optional
        The number of generations to run the search algorithm. Default is 100.
    initial_genome_size : Tuple[int, int], optional
        The range of genome sizes to produce during initialization. Default is
        (20, 100)
    simplification_steps : int
        The number of simplification iterations to apply to the best Push program
        produced by the search algorithm. Default 2000.
    interpreter : PushInterpreter, optional
        The PushInterpreter to use when making predictions. Also holds the instruction
        set to use
    parallelism : Union[Int, bool], optional
        Set the number of processes to spawn for use when performing embarrassingly
        parallel tasks. If false, no processes will spawn and compuation will be
        serial. Default is true, which spawns one process per available cpu.
    verbose : int, optional
        Indicates if verbose printing should be used during searching.
        Default is 0. Options are 0, 1, or 2.
    **kwargs
        Arbitrary keyword arguments. Examples of supported arguments are
        `epsilon` (bool or float) when using Lexicase as the selector, and
        `tournament_size` (int) when using tournament selection.

    """
    def __init__(self,
                 spawner: GeneSpawner,
                 search: str = "GA",
                 selector: Union[sl.Selector, str] = "lexicase",
                 variation_strategy: Union[vr.VariationStrategy, dict,
                                           str] = "umad",
                 population_size: int = 300,
                 max_generations: int = 100,
                 initial_genome_size: Tuple[int, int] = (20, 100),
                 simplification_steps: int = 2000,
                 last_str_from_stdout: bool = False,
                 interpreter: PushInterpreter = "default",
                 parallelism: Union[int, bool] = False,
                 push_config: PushConfig = "default",
                 verbose: int = 0,
                 **kwargs):
        self._search_name = search
        self.spawner = spawner
        self.selector = selector
        self.variation_strategy = variation_strategy
        self.population_size = population_size
        self.max_generations = max_generations
        self.initial_genome_size = initial_genome_size
        self.simplification_steps = simplification_steps
        self.last_str_from_stdout = last_str_from_stdout
        self.parallelism = parallelism
        self.verbose = verbose
        self.ext = kwargs
        set_verbosity(self.verbose)

        # Initialize attributes that will be set later.
        self.evaluator = None
        self.signature = None
        self.search = None
        self.solution = None

        if interpreter == "default":
            self.interpreter = PushInterpreter()
        else:
            self.interpreter = interpreter

        if push_config == "default":
            self.push_config = PushConfig()
        else:
            self.push_config = push_config

    def _build_search_algo(self):
        if isinstance(self.variation_strategy, dict):
            var_strat = vr.VariationStrategy()
            for op_name, prob in self.variation_strategy.items():
                var_op = vr.get_variation_operator(op_name)
                var_strat.add(var_op, prob)
            self.variation_strategy = var_strat

        search_config = sr.SearchConfiguration(
            signature=self.signature,
            spawner=self.spawner,
            evaluator=self.evaluator,
            selection=self.selector,
            variation=self.variation_strategy,
            population_size=self.population_size,
            max_generations=self.max_generations,
            initial_genome_size=self.initial_genome_size,
            simplification_steps=self.simplification_steps,
            parallelism=self.parallelism,
            push_config=self.push_config)
        self.search = sr.get_search_algo(self._search_name,
                                         config=search_config,
                                         **self.ext)

    @tap
    def fit(self, X, y):
        """Run the search algorithm to synthesize a push program.

        Parameters
        ----------
        X : pandas dataframe of shape = [n_samples, n_features]
            The training input samples.
        y : list, array-like, or pandas dataframe.
            The target values (class labels in classification, real numbers in
            regression). Shape = [n_samples] or [n_samples, n_outputs]

        """
        # arity is the number of inputs that the program takes.
        X, y, arity, y_types = check_X_y(X, y)
        output_types = [
            self.interpreter.type_library.push_type_for_type(t).name
            for t in y_types
        ]
        if self.last_str_from_stdout:
            ndx = list_rindex(output_types, "str")
            if ndx is not None:
                output_types[ndx] = "stdout"
        self.signature = ProgramSignature(arity=arity,
                                          output_stacks=output_types,
                                          push_config=self.push_config)
        self.evaluator = DatasetEvaluator(X, y, interpreter=self.interpreter)
        self._build_search_algo()
        self.solution = self.search.run()
        self.search.config.tear_down()

    def predict(self, X):
        """Execute the synthesized push program on a dataset.

        Parameters
        ----------
        X : pandas dataframe of shape = [n_samples, n_features]
            The set of cases to predict.

        Returns
        -------
        y_hat : pandas dataframe of shape = [n_samples, n_outputs]

        """
        check_is_fitted(self, "solution")
        return [
            self.interpreter.run(self.solution.program, inputs) for inputs in X
        ]

    def score(self, X, y):
        """Run the search algorithm to synthesize a push program.

        Parameters
        ----------
        X : pandas dataframe of shape = [n_samples, n_features]
            The training input samples.

        y : list, array-like, or pandas dataframe.
            The target values (class labels in classification, real numbers in
            regression). Shape = [n_samples] or [n_samples, n_outputs]

        """
        check_is_fitted(self, "solution")
        X, y, arity, y_types = check_X_y(X, y)
        self.evaluator = DatasetEvaluator(X, y, interpreter=self.interpreter)
        return self.evaluator.evaluate(self.solution.program)

    def save(self, filepath: str):
        """Load the found solution to a JSON file.

        Parameters
        ----------
        filepath
            Filepath to write the serialized search result to.

        """
        check_is_fitted(self, "solution")
        self.solution.save(filepath)

    def load(self, filepath: str):
        """Load a found solution from a JSON file.

        Parameters
        ----------
        filepath
            Filepath to read the serialized search result from.

        """
        self.solution = Individual.load(filepath)
예제 #34
0
    .register(point_distance_insrt)
    .register(point_from_floats_instr)
)

print(instruction_set.keys())

spawner = GeneSpawner(
    n_inputs=2,
    instruction_set=instruction_set,
    literals=[2.0],
    erc_generators=[]
)


# Our estimator with a custom interpreter defined.
est = PushEstimator(
    spawner=spawner,
    population_size=300,
    max_generations=20,
    simplification_steps=500,
    interpreter=PushInterpreter(instruction_set),
    verbose=2
)


if __name__ == "__main__":
    est.fit(X, y)
    print(est.solution.program)
    print(est.predict(X))
    print(est.score(X, y))