GrammaticalEvolutionTools 1.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- grammaticalevolutiontools-1.1.0a1/LICENSE +21 -0
- grammaticalevolutiontools-1.1.0a1/PKG-INFO +192 -0
- grammaticalevolutiontools-1.1.0a1/README.md +172 -0
- grammaticalevolutiontools-1.1.0a1/pyproject.toml +42 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/__init__.py +6 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/agents/__init__.py +4 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/agents/agent.py +212 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/agents/agent_program.py +105 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/evolution/__init__.py +10 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/evolution/cross_over.py +110 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/evolution/mutation.py +21 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/grammars/__init__.py +5 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/grammars/grammar.py +140 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/grammars/grammar_node.py +150 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/meta/__init__.py +5 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/meta/base_node.py +1261 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/meta/meta.py +273 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/__init__.py +3 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/base/__init__.py +4 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/base/program_node.py +644 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/base/program_tree.py +627 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/mods/__init__.py +0 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/mods/grammar/__init__.py +4 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/mods/grammar/grammar_program_addin.py +53 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/mods/grammar/node_converter.py +147 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/__init__.py +7 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/basic_nodes/__init__.py +6 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/basic_nodes/executable_node.py +14 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/basic_nodes/non_terminal_node.py +66 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/basic_nodes/root_node.py +37 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/basic_nodes/terminal_node.py +14 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/factor_nodes/__init__.py +6 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/factor_nodes/factor_node.py +34 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/factor_nodes/integer_node.py +20 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/factor_nodes/number_node.py +23 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/factor_nodes/rand_int_node.py +12 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/logic_nodes/__init__.py +5 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/logic_nodes/condition_node.py +101 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/logic_nodes/repeat_node.py +46 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/programs/nodes/logic_nodes/sequential_node.py +52 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/__init__.py +3 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/__init__.py +8 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/animation.py +28 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/layout.py +68 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/objects/__init__.py +4 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/objects/mixins/__init__.py +3 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/objects/mixins/reward.py +93 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/objects/world_object.py +71 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/position.py +92 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/base/world.py +142 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/__init__.py +10 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_layout.py +268 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_position.py +8 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_world.py +335 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_world_agent.py +186 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_world_animation.py +182 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_world_object.py +49 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/grid_world/grid_world_reward.py +24 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/hex_world/__init__.py +0 -0
- grammaticalevolutiontools-1.1.0a1/src/getools/worlds/open_world/__init__.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nicholas Smith
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: GrammaticalEvolutionTools
|
|
3
|
+
Version: 1.1.0a1
|
|
4
|
+
Summary: This package contains several tools for quickly setting up worlds and agents for Grammatical Evolution Projects.
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Nick Smith
|
|
8
|
+
Author-email: nicholas.smith0014@gmail.com
|
|
9
|
+
Requires-Python: >=3.13,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: ipykernel (>=7.0.1,<8.0.0)
|
|
15
|
+
Requires-Dist: matplotlib (>=3.10.1,<4.0.0)
|
|
16
|
+
Requires-Dist: scipy (>=1.16.2,<2.0.0)
|
|
17
|
+
Requires-Dist: seaborn (>=0.13.2,<0.14.0)
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# Grammatical Evolution Tools
|
|
21
|
+
|
|
22
|
+
[](https://www.python.org/downloads/)
|
|
23
|
+
[](https://github.com/n-smith-byu/GrammaticalEvolutionTools)
|
|
24
|
+
[](https://github.com/n-smith-byu/GrammaticalEvolutionTools/blob/main/LICENSE)
|
|
25
|
+
[](https://img.shields.io/badge/docs-under--construction-yellow)
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Table of Contents
|
|
32
|
+
* [Introduction](#introduction)
|
|
33
|
+
* [Features](#features)
|
|
34
|
+
* [Installation](#installation)
|
|
35
|
+
* [Prerequisites](#prerequisites)
|
|
36
|
+
* [Core Package](#core-package)
|
|
37
|
+
* [For Notebooks and Examples](#for-notebooks-and-examples)
|
|
38
|
+
* [For Development](#for-development)
|
|
39
|
+
* [Quick Start / Usage](#quick-start--usage)
|
|
40
|
+
* [Examples](#examples)
|
|
41
|
+
* [Running Tests](#running-tests)
|
|
42
|
+
* [Documentation](#documentation)
|
|
43
|
+
* [License](#license)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Introduction
|
|
48
|
+
|
|
49
|
+
`GrammaticalEvolutionTools` is a Python package designed to simplify the setup and execution of Grammatical Evolution (GE) and other Agent-Based Modeling (ABM) projects. It provides a suite of tools for quickly spinning up worlds, defining grammars, setting up agents, and running and animating simulations. It includes a number of abstract classes you can easily inherit from and customize, with much of the underlying functionality already implemented.
|
|
50
|
+
|
|
51
|
+
Whether you're building complex simulation environments or simple test cases, `getools` streamlines the boilerplate, enabling faster iteration and more effective research in grammatical evolution.
|
|
52
|
+
|
|
53
|
+
*Note: This project is still in development. Code has been refactored and not all docstrings may reflect this yet.*
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
### Currently Available:
|
|
58
|
+
* **World Environment Setup:** Easily define and configure custom environments for GE agents.
|
|
59
|
+
* **Grammar Definition:** Inherit from common classes to create custom grammars with specific functionalities.
|
|
60
|
+
* **Agent Management:** Logic for running Agent programs and having them interact with their world.
|
|
61
|
+
* **Evolution:** Common methods for cross over and mutation, built to work with program trees.
|
|
62
|
+
* **Animation:** Create customizable animations for simulations.
|
|
63
|
+
|
|
64
|
+
### Coming Soon:
|
|
65
|
+
* Asynchronous Behavior Trees!
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
Since this package is not yet published to PyPI, you will need to clone the repository and install it locally.
|
|
70
|
+
|
|
71
|
+
### Prerequisites
|
|
72
|
+
|
|
73
|
+
This project uses [Poetry](https://python-poetry.org/) for dependency management and packaging. Before installing the package, ensure you have Poetry installed on your system.
|
|
74
|
+
|
|
75
|
+
The recommended way to install Poetry is using `pipx`, which installs Python applications in isolated environments.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 1. Install pipx (if you don't have it)
|
|
79
|
+
python -m pip install --user pipx
|
|
80
|
+
python -m pipx ensurepath
|
|
81
|
+
|
|
82
|
+
# 2. Install Poetry using pipx
|
|
83
|
+
pipx install poetry
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You can find more detailed installation instructions for Poetry on their official website: [Poetry Installation Guide](https://python-poetry.org/docs/#installation)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Core Package
|
|
90
|
+
|
|
91
|
+
To install the core package with only its essential dependencies (for integrating it into your own projects):
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Clone the repository first
|
|
95
|
+
git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
96
|
+
cd getools
|
|
97
|
+
|
|
98
|
+
# Install the core package in editable mode
|
|
99
|
+
poetry install
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### To Run Notebooks and Examples
|
|
103
|
+
|
|
104
|
+
If you plan to explore the provided examples or run the Jupyter notebooks, you'll need to install the package with the `examples` dependency group.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# If you haven't already, clone the repository and navigate into it
|
|
108
|
+
# git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
109
|
+
# cd getools
|
|
110
|
+
|
|
111
|
+
# Install the package with examples dependencies
|
|
112
|
+
poetry install --with examples
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### For Development
|
|
116
|
+
|
|
117
|
+
If you intend to modify the code, run tests, or build the documentation, install with the `dev` dependency group.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# If you haven't already, clone the repository and navigate into it
|
|
121
|
+
# git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
122
|
+
# cd getools
|
|
123
|
+
|
|
124
|
+
# Install in editable mode with dev dependencies
|
|
125
|
+
poetry install --with dev
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Examples
|
|
131
|
+
|
|
132
|
+
The `examples/` directory in this repository contains various Jupyter notebooks and scripts demonstrating how to use `getools` for different scenarios.
|
|
133
|
+
|
|
134
|
+
To run these examples, make sure you have installed the package with the `examples` dependency group:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Ensure you are in the project root directory
|
|
138
|
+
cd examples/
|
|
139
|
+
jupyter lab # or jupyter notebook
|
|
140
|
+
```
|
|
141
|
+
Examples include an implementation of the Santa Fe problem and a basic grammatical evolution algorithm.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Running Tests
|
|
146
|
+
|
|
147
|
+
*NOTE: Incomplete*
|
|
148
|
+
|
|
149
|
+
If you are developing the package, you can run the test suite using `pytest`. Ensure you have installed the `dev` dependencies.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# From the project root directory
|
|
153
|
+
pytest
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Documentation
|
|
159
|
+
|
|
160
|
+
*NOTE: Incomplete*
|
|
161
|
+
|
|
162
|
+
The project's documentation is built using Sphinx. To generate the HTML documentation locally, ensure you have installed the `dev` dependencies.
|
|
163
|
+
|
|
164
|
+
First, navigate to the `docs/` directory from the project root:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
cd docs/
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Then, run the appropriate command for your operating system:
|
|
171
|
+
|
|
172
|
+
**For Linux / macOS / WSL:**
|
|
173
|
+
```bash
|
|
174
|
+
make html
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**For Windows (Command Prompt / PowerShell):**
|
|
178
|
+
```bash
|
|
179
|
+
poetry run sphinx-build -b html . _build/html
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The generated HTML documentation will be located in `docs/_build/html/index.html`. You can open this file in your web browser to view the documentation.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
This project is licensed under the [MIT License](https://github.com/n-smith-byu/GrammaticalEvolutionTools/blob/main/LICENSE).
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Grammatical Evolution Tools
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://github.com/n-smith-byu/GrammaticalEvolutionTools)
|
|
5
|
+
[](https://github.com/n-smith-byu/GrammaticalEvolutionTools/blob/main/LICENSE)
|
|
6
|
+
[](https://img.shields.io/badge/docs-under--construction-yellow)
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Table of Contents
|
|
13
|
+
* [Introduction](#introduction)
|
|
14
|
+
* [Features](#features)
|
|
15
|
+
* [Installation](#installation)
|
|
16
|
+
* [Prerequisites](#prerequisites)
|
|
17
|
+
* [Core Package](#core-package)
|
|
18
|
+
* [For Notebooks and Examples](#for-notebooks-and-examples)
|
|
19
|
+
* [For Development](#for-development)
|
|
20
|
+
* [Quick Start / Usage](#quick-start--usage)
|
|
21
|
+
* [Examples](#examples)
|
|
22
|
+
* [Running Tests](#running-tests)
|
|
23
|
+
* [Documentation](#documentation)
|
|
24
|
+
* [License](#license)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Introduction
|
|
29
|
+
|
|
30
|
+
`GrammaticalEvolutionTools` is a Python package designed to simplify the setup and execution of Grammatical Evolution (GE) and other Agent-Based Modeling (ABM) projects. It provides a suite of tools for quickly spinning up worlds, defining grammars, setting up agents, and running and animating simulations. It includes a number of abstract classes you can easily inherit from and customize, with much of the underlying functionality already implemented.
|
|
31
|
+
|
|
32
|
+
Whether you're building complex simulation environments or simple test cases, `getools` streamlines the boilerplate, enabling faster iteration and more effective research in grammatical evolution.
|
|
33
|
+
|
|
34
|
+
*Note: This project is still in development. Code has been refactored and not all docstrings may reflect this yet.*
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
### Currently Available:
|
|
39
|
+
* **World Environment Setup:** Easily define and configure custom environments for GE agents.
|
|
40
|
+
* **Grammar Definition:** Inherit from common classes to create custom grammars with specific functionalities.
|
|
41
|
+
* **Agent Management:** Logic for running Agent programs and having them interact with their world.
|
|
42
|
+
* **Evolution:** Common methods for cross over and mutation, built to work with program trees.
|
|
43
|
+
* **Animation:** Create customizable animations for simulations.
|
|
44
|
+
|
|
45
|
+
### Coming Soon:
|
|
46
|
+
* Asynchronous Behavior Trees!
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
Since this package is not yet published to PyPI, you will need to clone the repository and install it locally.
|
|
51
|
+
|
|
52
|
+
### Prerequisites
|
|
53
|
+
|
|
54
|
+
This project uses [Poetry](https://python-poetry.org/) for dependency management and packaging. Before installing the package, ensure you have Poetry installed on your system.
|
|
55
|
+
|
|
56
|
+
The recommended way to install Poetry is using `pipx`, which installs Python applications in isolated environments.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# 1. Install pipx (if you don't have it)
|
|
60
|
+
python -m pip install --user pipx
|
|
61
|
+
python -m pipx ensurepath
|
|
62
|
+
|
|
63
|
+
# 2. Install Poetry using pipx
|
|
64
|
+
pipx install poetry
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can find more detailed installation instructions for Poetry on their official website: [Poetry Installation Guide](https://python-poetry.org/docs/#installation)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Core Package
|
|
71
|
+
|
|
72
|
+
To install the core package with only its essential dependencies (for integrating it into your own projects):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Clone the repository first
|
|
76
|
+
git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
77
|
+
cd getools
|
|
78
|
+
|
|
79
|
+
# Install the core package in editable mode
|
|
80
|
+
poetry install
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### To Run Notebooks and Examples
|
|
84
|
+
|
|
85
|
+
If you plan to explore the provided examples or run the Jupyter notebooks, you'll need to install the package with the `examples` dependency group.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# If you haven't already, clone the repository and navigate into it
|
|
89
|
+
# git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
90
|
+
# cd getools
|
|
91
|
+
|
|
92
|
+
# Install the package with examples dependencies
|
|
93
|
+
poetry install --with examples
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### For Development
|
|
97
|
+
|
|
98
|
+
If you intend to modify the code, run tests, or build the documentation, install with the `dev` dependency group.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# If you haven't already, clone the repository and navigate into it
|
|
102
|
+
# git clone [https://github.com/n-smith-byu/getools.git](https://github.com/n-smith-byu/GrammaticalEvolutionTools.git)
|
|
103
|
+
# cd getools
|
|
104
|
+
|
|
105
|
+
# Install in editable mode with dev dependencies
|
|
106
|
+
poetry install --with dev
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Examples
|
|
112
|
+
|
|
113
|
+
The `examples/` directory in this repository contains various Jupyter notebooks and scripts demonstrating how to use `getools` for different scenarios.
|
|
114
|
+
|
|
115
|
+
To run these examples, make sure you have installed the package with the `examples` dependency group:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Ensure you are in the project root directory
|
|
119
|
+
cd examples/
|
|
120
|
+
jupyter lab # or jupyter notebook
|
|
121
|
+
```
|
|
122
|
+
Examples include an implementation of the Santa Fe problem and a basic grammatical evolution algorithm.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Running Tests
|
|
127
|
+
|
|
128
|
+
*NOTE: Incomplete*
|
|
129
|
+
|
|
130
|
+
If you are developing the package, you can run the test suite using `pytest`. Ensure you have installed the `dev` dependencies.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# From the project root directory
|
|
134
|
+
pytest
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Documentation
|
|
140
|
+
|
|
141
|
+
*NOTE: Incomplete*
|
|
142
|
+
|
|
143
|
+
The project's documentation is built using Sphinx. To generate the HTML documentation locally, ensure you have installed the `dev` dependencies.
|
|
144
|
+
|
|
145
|
+
First, navigate to the `docs/` directory from the project root:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd docs/
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Then, run the appropriate command for your operating system:
|
|
152
|
+
|
|
153
|
+
**For Linux / macOS / WSL:**
|
|
154
|
+
```bash
|
|
155
|
+
make html
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**For Windows (Command Prompt / PowerShell):**
|
|
159
|
+
```bash
|
|
160
|
+
poetry run sphinx-build -b html . _build/html
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The generated HTML documentation will be located in `docs/_build/html/index.html`. You can open this file in your web browser to view the documentation.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
This project is licensed under the [MIT License](https://github.com/n-smith-byu/GrammaticalEvolutionTools/blob/main/LICENSE).
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
---
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "GrammaticalEvolutionTools"
|
|
3
|
+
version = "1.1.0a1"
|
|
4
|
+
description = "This package contains several tools for quickly setting up worlds and agents for Grammatical Evolution Projects."
|
|
5
|
+
authors = ["Nick Smith <nicholas.smith0014@gmail.com>"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
packages = [
|
|
9
|
+
{ include = "getools", from = "src" }
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
[tool.poetry.dependencies]
|
|
13
|
+
python = ">=3.13,<4.0"
|
|
14
|
+
matplotlib = ">=3.10.1,<4.0.0"
|
|
15
|
+
seaborn = ">=0.13.2,<0.14.0"
|
|
16
|
+
ipykernel = "^7.0.1"
|
|
17
|
+
scipy = "^1.16.2"
|
|
18
|
+
|
|
19
|
+
[tool.poetry.group.dev]
|
|
20
|
+
optional = true
|
|
21
|
+
|
|
22
|
+
[tool.poetry.group.dev.dependencies]
|
|
23
|
+
sphinx-rtd-theme = "^3.0.2"
|
|
24
|
+
numpydoc = "^1.9.0"
|
|
25
|
+
pytest-mock = "^3.14.1"
|
|
26
|
+
sphinx = "^9.0.4"
|
|
27
|
+
pytest = "^9.0.2"
|
|
28
|
+
|
|
29
|
+
[tool.poetry.group.examples]
|
|
30
|
+
optional = true
|
|
31
|
+
|
|
32
|
+
[tool.poetry.group.examples.dependencies]
|
|
33
|
+
notebook = "^7.4.4"
|
|
34
|
+
tqdm = "^4.67.1"
|
|
35
|
+
ipympl = "^0.9.8"
|
|
36
|
+
|
|
37
|
+
[tool.pytest.ini_options]
|
|
38
|
+
pythonpath = ["."]
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
42
|
+
build-backend = "poetry.core.masonry.api"
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from .agent_program import AgentProgramTree
|
|
2
|
+
from ..grammars import Grammar
|
|
3
|
+
|
|
4
|
+
from numbers import Number
|
|
5
|
+
from uuid import uuid4
|
|
6
|
+
|
|
7
|
+
from typing import Type, TYPE_CHECKING
|
|
8
|
+
import warnings
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..worlds import World
|
|
12
|
+
|
|
13
|
+
class Agent:
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def default_grammar(cls) -> Grammar:
|
|
17
|
+
return cls._default_grammar
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def default_program_cls(cls) -> Type[AgentProgramTree]:
|
|
21
|
+
mangled = f"_{cls.__name__}__default_program_cls"
|
|
22
|
+
|
|
23
|
+
if not hasattr(cls, mangled):
|
|
24
|
+
default_grammar = cls.default_grammar()
|
|
25
|
+
if default_grammar:
|
|
26
|
+
class AgentProgram(AgentProgramTree):
|
|
27
|
+
_grammar = default_grammar
|
|
28
|
+
pass
|
|
29
|
+
setattr(cls, mangled, AgentProgram)
|
|
30
|
+
|
|
31
|
+
return getattr(cls, mangled, None)
|
|
32
|
+
|
|
33
|
+
_default_grammar = None
|
|
34
|
+
_requires_world = False
|
|
35
|
+
|
|
36
|
+
# - - Exceptions - -
|
|
37
|
+
|
|
38
|
+
class WorldNotSetError(RuntimeError):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
class AlreadyInWorldError(RuntimeError):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
class AssignedProgramError(RuntimeError):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
class NotAssignedProgramError(RuntimeError):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
# - - Initialization - -
|
|
51
|
+
|
|
52
|
+
def __init__(self, program: AgentProgramTree = None, autogen=True):
|
|
53
|
+
self._world: World = None
|
|
54
|
+
self._program: AgentProgramTree = None
|
|
55
|
+
self._uuid = uuid4() # just to make hashable
|
|
56
|
+
|
|
57
|
+
self._score = 0
|
|
58
|
+
self._num_actions = 0
|
|
59
|
+
|
|
60
|
+
if program:
|
|
61
|
+
self._assert_valid_program(program)
|
|
62
|
+
self._set_program(program)
|
|
63
|
+
elif autogen:
|
|
64
|
+
program_cls = self.default_program_cls()
|
|
65
|
+
if not program_cls:
|
|
66
|
+
warnings.warn(
|
|
67
|
+
"`autogen` set to True, but no default " \
|
|
68
|
+
"grammar found for " \
|
|
69
|
+
f"{type(self).__name__}. Could not create a program.",
|
|
70
|
+
UserWarning
|
|
71
|
+
)
|
|
72
|
+
else:
|
|
73
|
+
self._set_program(program_cls())
|
|
74
|
+
|
|
75
|
+
# - - Assertions - -
|
|
76
|
+
|
|
77
|
+
def _assert_not_in_world(self):
|
|
78
|
+
if self.assigned_to_world():
|
|
79
|
+
raise Agent.AlreadyInWorldError(
|
|
80
|
+
"Cannot add agent to world because agent is already in another world. "
|
|
81
|
+
"Remove agent from that world first. "
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def _assert_not_assigned_program(self):
|
|
85
|
+
if self._program:
|
|
86
|
+
raise Agent.AssignedProgramError(
|
|
87
|
+
"Cannot set program when agent is already assigned a program. "
|
|
88
|
+
"Please remove old program first."
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def _assert_valid_program(self, program):
|
|
92
|
+
if not isinstance(program, AgentProgramTree):
|
|
93
|
+
raise TypeError('program must be an instance of AgentProgramTree.')
|
|
94
|
+
if program.agent and program.agent is not self:
|
|
95
|
+
raise ValueError(
|
|
96
|
+
"Cannot bind program to this agent when program is already "
|
|
97
|
+
"bound to another agent. Unbind the program first."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# - - World Internal Access - -
|
|
101
|
+
|
|
102
|
+
def _set_world(self, world: 'World'):
|
|
103
|
+
self._assert_not_in_world()
|
|
104
|
+
|
|
105
|
+
self._world = world
|
|
106
|
+
|
|
107
|
+
def _clear_world(self):
|
|
108
|
+
self._world = None
|
|
109
|
+
|
|
110
|
+
# - - Helpers - -
|
|
111
|
+
|
|
112
|
+
def _set_program(self, program: AgentProgramTree):
|
|
113
|
+
self._program = program
|
|
114
|
+
if program:
|
|
115
|
+
program._set_agent(self)
|
|
116
|
+
|
|
117
|
+
def _remove_program(self) -> AgentProgramTree:
|
|
118
|
+
program = self._program
|
|
119
|
+
program._set_agent(None)
|
|
120
|
+
self._program = None
|
|
121
|
+
|
|
122
|
+
return program
|
|
123
|
+
|
|
124
|
+
def _replace_program(self, new_program: AgentProgramTree) -> AgentProgramTree:
|
|
125
|
+
old = self._remove_program()
|
|
126
|
+
try:
|
|
127
|
+
self._set_program(new_program)
|
|
128
|
+
except (TypeError, ValueError) as e:
|
|
129
|
+
self._set_program(old)
|
|
130
|
+
raise e
|
|
131
|
+
|
|
132
|
+
return old
|
|
133
|
+
|
|
134
|
+
# - - Public - -
|
|
135
|
+
|
|
136
|
+
def reset(self, program: AgentProgramTree = None):
|
|
137
|
+
if program:
|
|
138
|
+
self._assert_valid_program(program)
|
|
139
|
+
self._replace_program(program)
|
|
140
|
+
|
|
141
|
+
if self._program and self._program.running():
|
|
142
|
+
self._program.kill()
|
|
143
|
+
|
|
144
|
+
self._num_actions = 0
|
|
145
|
+
self._score = 0
|
|
146
|
+
|
|
147
|
+
def copy_program(self):
|
|
148
|
+
return self._program.copy()
|
|
149
|
+
|
|
150
|
+
# - - Running Program - -
|
|
151
|
+
|
|
152
|
+
def execute_program(self, n=1):
|
|
153
|
+
"""
|
|
154
|
+
Resets the program and runs to completion once.
|
|
155
|
+
"""
|
|
156
|
+
if self._program.running():
|
|
157
|
+
self._program.kill()
|
|
158
|
+
|
|
159
|
+
self._program.run(n=n)
|
|
160
|
+
|
|
161
|
+
def tick(self, loop: bool=True):
|
|
162
|
+
"""
|
|
163
|
+
Runs the program through the next executable node. Exits if run and no nodes are left.
|
|
164
|
+
If loop is True (default), then the program will restart rather than exiting.
|
|
165
|
+
"""
|
|
166
|
+
if self._requires_world and not self.assigned_to_world():
|
|
167
|
+
raise Agent.WorldNotSetError("Cannot run program without agent being assigned a world unless this is a worldless agent.")
|
|
168
|
+
|
|
169
|
+
status = self._program.tick()
|
|
170
|
+
if status == AgentProgramTree.Status.EXITED and loop:
|
|
171
|
+
self._program.tick()
|
|
172
|
+
|
|
173
|
+
def give_reward(self, amount):
|
|
174
|
+
self._score += amount
|
|
175
|
+
|
|
176
|
+
# - - Listeners - -
|
|
177
|
+
|
|
178
|
+
def _on_action_taken(self):
|
|
179
|
+
self._record_action()
|
|
180
|
+
|
|
181
|
+
# - - Operations - -
|
|
182
|
+
|
|
183
|
+
def _record_action(self):
|
|
184
|
+
self._num_actions += 1
|
|
185
|
+
|
|
186
|
+
# - - Getters - -
|
|
187
|
+
|
|
188
|
+
def assigned_to_world(self):
|
|
189
|
+
return self._world is not None
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def program(self) -> AgentProgramTree:
|
|
193
|
+
return self._program
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def score(self) -> Number:
|
|
197
|
+
return self._score
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def num_actions(self) -> int:
|
|
201
|
+
return self._num_actions
|
|
202
|
+
|
|
203
|
+
# - - Other Methods - -
|
|
204
|
+
|
|
205
|
+
def __hash__(self):
|
|
206
|
+
return hash(self._uuid)
|
|
207
|
+
|
|
208
|
+
def __lt__(self, other):
|
|
209
|
+
if not isinstance(other, Agent):
|
|
210
|
+
raise TypeError("Cannot compare Agent to non-Agent")
|
|
211
|
+
|
|
212
|
+
return self.score < other.score
|