Skip to content

Commit

Permalink
Added program factory skeleton implementation (#3)
Browse files Browse the repository at this point in the history
Implemented Program Factories, including a concrete implementation for Random Program generation, docs, tests, and coverage.
  • Loading branch information
fairlight1337 authored Jan 25, 2023
1 parent 1196091 commit d4c5a6d
Show file tree
Hide file tree
Showing 15 changed files with 673 additions and 10 deletions.
18 changes: 16 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,29 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.1.1]

### Added

- A base class for Program Factories: ProgramFactoryBase
- A concrete implementation of the base class for random programs: RandomProgramFactory
- Covered the random programs factory via tests
- Updated the Sphinx documentation to cover program factories
- Added an end-of-list size entry to the beast::OpCode enum
- Fixed long-standing AppVeyor signedness warnings
- Updated roadmap for program generators

### Fixed

- Fixed size program initialization is done via an unsigned value, not signed

## [0.1.0]

### Added

- Base class for Virtual Machine implementation.
- Concrete CPU-based implementation of a Virtual Machine.
- Definition of 76 operators to use in BEAST byte code programs.
- Definition of 77 operators to use in BEAST byte code programs.
- Classes for storing byte code programs and their execution state in a VM.
- Added examples (feedloop, adder, hello_world, bubblesort) for implementing
programs in byte code.
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.8)
project(beast
LANGUAGES CXX
VERSION 0.1.0
VERSION 0.1.1
DESCRIPTION "Byte code generator, parser, and virtual machine for evaluating evolutionary code sequences."
HOMEPAGE_URL "https://github.com/dedicate-project/beast/")

Expand Down Expand Up @@ -58,6 +58,7 @@ add_library(${PROJECT_NAME}
src/beast.cpp
src/cpu_virtual_machine.cpp
src/program.cpp
src/random_program_factory.cpp
src/time_functions.cpp
src/vm_session.cpp
src/virtual_machine.cpp)
Expand Down Expand Up @@ -115,6 +116,7 @@ if(BEAST_BUILD_TESTS)
declare_test(misc)
declare_test(printing_and_string_table)
declare_test(program)
declare_test(random_program_factory)
declare_test(stacks)
declare_test(system_calls)
declare_test(variables)
Expand Down
4 changes: 3 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
- [x] Add more examples for how to use the virtual machine and implemented operators

## Stage 2: Genetic Algorithms and Program Evaluation
- [ ] Develop an environment where programs are semi-randomly generated and can be evaluated based on manually defined criteria
- [x] Develop program factories that semi-randomly generate programs
- [ ] Develop runtime statistics protocols that record specific execution characteristics of programs
- [ ] Develop program performance evaluators, taking into account runtime statistics, but also specific criteria that programs are supposed to satisfy, and scoring them
- [ ] Develop a genetic algorithms based approach to recombining programs that perform well based on the implemented criteria

## Stage 3: High level Language
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def configureDoxyfile(input_dir, output_dir):
breathe_projects['BEAST'] = output_dir + '/xml'

project = 'BEAST'
copyright = '2022, Jan Winkler'
copyright = '2022-2023, Jan Winkler'
author = 'Jan Winkler'
master_doc = 'index'

Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ BEAST (Binary Evolution And Sentience Toolkit) is an open source project `hosted
:caption: Project Table of Contents

bytecode_virtual_machine.rst
program_factories.rst


Project Synopsis
Expand Down
53 changes: 53 additions & 0 deletions docs/program_factories.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Program Factories
=================

To generate Program instances based on certain criteria rather than programming them manually every
time, program factories are introduced. They allow to generate ready-made Program instances with a
straight forward interface, requiring only the expected size of the program, and the runtime
environment parameters the programs are expected to be run under (variable memory size, string table
size, string table item length limit). The generic interface for these factories is governed by a
:ref:`Program Factory Base` class, while concrete implementations may offer more (optional)
customization options beyond it, steering the generation process towards specific requirements.

In this document, the :ref:`Program Factory Base` as well as the :ref:`Random Program Factory`
classes are introduced. The latter generates programs randomly, but in a valid way. More factories
may be added in the future on a per-need-basis.


Program Factory Base
--------------------

This is the base class for all program factories. It dictates a simple interface requiring the size
of the expected programs to be generated, and the runtime environment they are expected to be
executed under. The central call for all factories is the `generate()` function, which returns the
generated Program instances.

.. doxygenclass:: beast::ProgramFactoryBase
:members:


Random Program Factory
----------------------

This concrete implementation of the :ref:`Program Factory Base` interface class generated random
programs. These programs make use of the full scope of operators available in the BEAST library. All
Program instances generated by this factory adhere to proper OpCodes (no invalid OpCodes are used),
and correctly align their parameters, bit-wise and semantically. This means that per operator, all
parameters are in the correct position and have reasonable values based on the environment passed to
the `generate()` function:

* Variables are only declared/used in the range of the passed in variable memory space
* String table entries are only read/written in the range of the passed in string table size
* String table entry content is only generated with valid lengths (although still random)

Also, expected parameter ranges are adhered to (operands are distinguished between `int32_t`,
`int8_t`, and `bool` accordingly). Program instances generated by this class likely don't make sense
logically, but semantically they are correct. These programs can be used as seed material for random
recombination, ensuring that at least the semantic layer is close to what is executable within the
BEAST environment.

Future plans for this class include adding an option to exclude specific operators from the
generation process.

.. doxygenclass:: beast::RandomProgramFactory
:members:
1 change: 1 addition & 0 deletions include/beast/beast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <beast/cpu_virtual_machine.hpp>
#include <beast/opcodes.hpp>
#include <beast/program.hpp>
#include <beast/random_program_factory.hpp>
#include <beast/time_functions.hpp>
#include <beast/version.h>
#include <beast/vm_session.hpp>
Expand Down
4 changes: 3 additions & 1 deletion include/beast/opcodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ enum class OpCode : int8_t {
PopVariableFromStack = 0x4a, ///< Pop the top item from a stack into a
/// variable
PopTopItemFromStack = 0x4b, ///< Pop the top item from a stack
CheckIfStackIsEmpty = 0x4c ///< Check if a stack contains no items
CheckIfStackIsEmpty = 0x4c, ///< Check if a stack contains no items

Size = 0x4d ///< Used to determine operator count
};

} // namespace beast
Expand Down
2 changes: 1 addition & 1 deletion include/beast/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Program {
*
* @param space The constant space available in the program.
*/
explicit Program(int32_t space);
explicit Program(uint32_t space);

/**
* @fn Program::Program(std::vector<unsigned char>)
Expand Down
52 changes: 52 additions & 0 deletions include/beast/program_factory_base.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef BEAST_PROGRAM_FACTORY_BASE_HPP_
#define BEAST_PROGRAM_FACTORY_BASE_HPP_

// Internal
#include <beast/program.hpp>

namespace beast {

/**
* @class ProgramFactoryBase
* @brief Base class for program factories
*
* Program factories generate programs based on high level parameters and criteria. A concrete
* implementation of a factory can have a multitude of parameterization options that define the
* characteristics of the generated programs.
*/
class ProgramFactoryBase {
public:
/**
* @fn ProgramFactoryBase::~ProgramFactoryBase
* @brief Default virtual destructor
*
* Ensures vtable consistency.
*/
virtual ~ProgramFactoryBase() = default;

/**
* @fn ProgramFactoryBase::generate
* @brief Generates a program based on the factory's semantics
*
* Generates a Program instance that follows the factory's concrete implementation's
* characteristics. The given parameters that define a runtime-parameterization are used to make
* an educated guess on how to make the generated program executable. For example, only variables
* may be declared or used whose indices lie within the expected memory size to avoid illogical
* program traits. The concrete use of these parameters, if any, depends on the respective
* implementation of the factory though.
*
* @param size The maximum size of the program to generate, in bytes
* @param memory_size The memory size the generated program would be executed with
* @param string_table_size The string table size the generated program would be executed with
* @param string_table_item_length The string table item length the generated program would be
* executed with
* @return The generated Program instance
*/
virtual Program generate(
uint32_t size, uint32_t memory_size, uint32_t string_table_size,
uint32_t string_table_item_length) = 0;
};

} // namespace beast

#endif // BEAST_PROGRAM_FACTORY_BASE_HPP_
42 changes: 42 additions & 0 deletions include/beast/random_program_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef BEAST_RANDOM_PROGRAM_FACTORY_HPP_
#define BEAST_RANDOM_PROGRAM_FACTORY_HPP_

// Internal
#include <beast/program_factory_base.hpp>

namespace beast {

/**
* @class RandomProgramFactory
* @brief Generates random programs with a valid structure
*
* This implementation of the abstract ProgramFactoryBase class can be used to generate Program
* instances that have a random, albeit valid structure. Only valid operators are used in the
* respective programs, the operators are aligned correctly, and variable indices, string table
* indices, and string lengths are all within bounds of the passed in runtime environment
* parameters.
*/
class RandomProgramFactory : public ProgramFactoryBase {
public:
/**
* @fn RandomProgramFactory::generate
* @brief Generates a program consisting of random but valid operators and operands
*
* The programs generated by this function make use of the full operator set supported by the
* BEAST library.
*
* @param size The maximum size of the program to generate, in bytes
* @param memory_size The memory size the generated program would be executed with
* @param string_table_size The string table size the generated program would be executed with
* @param string_table_item_length The string table item length the generated program would be
* executed with
* @return A randomly generated, but valid program
*/
Program generate(
uint32_t size, uint32_t memory_size, uint32_t string_table_size,
uint32_t string_table_item_length) override;
};

} // namespace beast

#endif // BEAST_RANDOM_PROGRAM_FACTORY_HPP_
4 changes: 2 additions & 2 deletions src/cpu_virtual_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ bool CpuVirtualMachine::step(VmSession& session) {
const int32_t string_table_index = session.getData4();
const int16_t string_length = session.getData2();
std::vector<char> buffer(string_length);
for (unsigned int idx = 0; idx < string_length; ++idx) {
for (int32_t idx = 0; idx < string_length; ++idx) {
buffer[idx] = session.getData1();
}
const auto string_content = std::string(buffer.data(), string_length);
Expand Down Expand Up @@ -596,7 +596,7 @@ bool CpuVirtualMachine::step(VmSession& session) {
const bool follow_links = session.getData1() != 0x0;
const int16_t string_length = session.getData2();
std::vector<char> buffer(string_length);
for (unsigned int idx = 0; idx < string_length; ++idx) {
for (int32_t idx = 0; idx < string_length; ++idx) {
buffer[idx] = session.getData1();
}
const auto string_content = std::string(buffer.data(), string_length);
Expand Down
2 changes: 1 addition & 1 deletion src/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace beast {

Program::Program(int32_t space)
Program::Program(uint32_t space)
: data_(space, 0x00), grows_dynamically_{false} {
}

Expand Down
Loading

0 comments on commit d4c5a6d

Please sign in to comment.