added docstrings to problems

This commit is contained in:
Ashley Bao 2023-01-13 17:39:28 -05:00
parent 4f2db7a406
commit b6b7a5bf9b
95 changed files with 2678 additions and 190 deletions

201
doc/Intro.md Normal file
View File

@ -0,0 +1,201 @@
# Introduction to Propeller
**Propeller** is an implementation of the Push programming language and the PushGP genetic programming system in Clojure.
For more information on Push and PushGP see http://pushlanguage.org.
## Overview
**Propeller** is a Push-based genetic programming system in Clojure.
<!-- TOC -->
* [Introduction to Propeller](#introduction-to-propeller)
* [Overview](#overview)
* [What can you do with propeller?](#what-can-you-do-with-propeller)
* [Installation](#installation)
* [How do I run a problem in propeller?](#how-do-i-run-a-problem-in-propeller)
* [An Example](#an-example)
* [Can you use a REPL?](#can-you-use-a-repl)
* [Tutorials](#tutorials)
* [Contributing](#contributing)
* [License](#license)
* [Citation](#citation)
* [About Propeller](#about-propeller)
* [Contact](#contact)
* [Library Reference](#library-reference)
<!-- TOC -->
### What can you do with Propeller?
You can evolve a program made of Push instructions to solve a problem.
## Installation
You can use either leiningen or deps.edn to run Propeller.
If you have installed [leiningen](https://leiningen.org), which is a tool
for running Clojure programs, then you can run Propeller on a genetic
programming problem that is defined within this project from the command
line with the command `lein run -m <namespace>`, replacing `<namespace>`
with the actual namespace that you will find at the top of the problem file.
If you have installed [Clojure](https://clojure.org/guides/install_clojure#java),
you can run Propeller on a genetic programming problem with the command `clj -m <namespace>`,
replacing `<namespace>` with the actual namespace that you will find at the top of the problem file.
The examples below use leiningen, but you can replace `lein run` with `clj` to run the same problem.
## How do I run a problem in propeller?
To run a problem in propeller, you want to call the `-main` function in the problem file using leiningen.
The `-main` function will create a map of arguments from the input and run the main genetic programming loop.
Below is the general format to run a problem through the command-line:
```
lein run -m <namespace of the problem file you want to test>
```
Additional command-line arguments may
be provided to override the default key/value pairs specified in the
problem file,
```
lein run -m <namespace of the problem file you want to test> <key and value> <key and value>...
```
The possible keys come from the table below:
| Key | Description |
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `:instructions` | List of possible Push instructions used to create a plushy |
| `:error-function` | The error function used to evaluate individuals, specified in the given problem's namespace |
| `:training-data` | Map of inputs and desired outputs used to evaluate individuals of the form: {:input1 first-input :input2 second-input ... :output1 first-output ...} |
| `:testing-data` | Map of inputs and desired outputs not in the training-data to test generalizability of a program that fits the `training-data`. The map is of the form: {:input1 first-input :input2 second-input ... :output1 first-output ...} |
| `:max-generations` | Maximum number of generations |
| `:population-size` | Size of population in a generation |
| `:max-initial-plushy-size` | Maximum number of Push instructions in the initial plushy |
| `:step-limit` | The maximum number of steps that a Push program will be executed by `interpret-program` |
| `:parent-selection` | Function from `propeller.selection` that determines method of parent selection method. Propeller includes `:tournament-selection`, `:lexicase-selection`, and `:epsilon-lexicase-selection`. |
| `:tournament-size` | If using a tournament selection method, the number of individuals in each tournaments used to determine parents |
| `:umad-rate` | Rate (decimal between 0 and 1) of uniform mutation by addition and deletion (UMAD) genetic operator |
| `:variation` | Map with genetic operators as keys and probabilities as values. For example, {:umad 0.3 :crossover 0.7}. This would mean that when the system needs to generate a child, it will use UMAD 30% of the time and crossover 70% of the time. The probabilities should sum to 1. |
| `:elitism` | When true, will cause the individual with the lowest error in the population to survive, without variation, into the next generation. |
When you run a problem, you will get a report each generation with the following information:
```
:generation
:best-plushy
:best-program
:best-total-error
:best-errors
:best-behaviors
:genotypic-diversity
:behavioral-diversity
:average-genome-length
:average-total-error
```
### An Example
For example, you can run the simple-regression genetic programming problem with:
```
lein run -m propeller.problems.simple-regression
```
This will run simple-regression with the default set of arguments in the `simple-regression` problem file.
```
{:instructions instructions
:error-function error-function
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)
:max-generations 500
:population-size 500
:max-initial-plushy-size 100
:step-limit 200
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 0.5 :crossover 0.5}
:elitism false}
```
You can override the default key/value pairs with additional arguments. For example:
```
lein run -m propeller.problems.simple-regression :population-size 100
```
On Unix operating systems, including MacOS, you can use something
like the following to send output both to the terminal
and to a text file (called `outfile` in this example):
```
lein run -m propeller.problems.simple-regression | tee outfile
```
If you want to provide command line arguments that include
characters that may be interpreted by your command line shell
before they get to Clojure, then enclose those in double
quotes, like in this example that provides a non-default
value for the `:variation` argument, which is a clojure map
containing curly brackets that may confuse your shell:
```
lein run -m propeller.problems.simple-regression :variation "{:umad 1.0}"
```
### Can you use a REPL?
Yes!
To run a genetic programming problem from a REPL, start
your REPL for the project (e.g. with `lein repl` at the
command line when in the project directory, or through your
IDE) and then do something like the following (which in
this case runs the simple-regression problem with
`:population-size` 100):
```
(require 'propeller.problems.simple-regression)
(in-ns 'propeller.problems.simple-regression)
(-main :population-size 100 :variation {:umad 1.0})
```
If you want to run the problem with the default parameters,
then you should call `-main` without arguments, as `(-main).
## Tutorials
- Adding genetic operators
- Adding selection methods
- Adding a new problem
- How to use simplification
- Experimentation Guide
## Contributing
You can report a bug on the [GitHub issues page](https://github.com/lspector/propeller/issues).
The best way to contribute to propeller is to fork the [main GitHub repository](https://github.com/lspector/propeller) and submit a pull request.
## License
Eclipse Public License 2.0
This commercially-friendly copyleft license provides the ability to commercially license binaries;
a modern royalty-free patent license grant; and the ability for linked works to use other licenses, including commercial ones.
## Citation
We are in the process of creating a DOI, but in the meantime, we ask
that you cite the [link to the repository](https://github.com/lspector/propeller) if you use Propeller.
## About Propeller
https://deap.readthedocs.io/en/master/about.html
## Contact
## Library Reference

View File

@ -0,0 +1,62 @@
# Adding Genetic Operators
In addition to the already-included genetic operators, you can add your own!
## Variation Genetic Operators
1. Go to `propeller.variation.cljc`
2. Define a genetic operator function
3. In `propeller.variation/new-individual`, add the new genetic operator in the `new-individual` function under the `case` call
```clojure
(defn new-individual
"Returns a new individual produced by selection and variation of
individuals in the population."
[pop argmap]
...
(case op
...
:new-genetic-operator
(-> (:plushy (selection/select-parent pop argmap))
(new-genetic-operator ))
...
:else
(throw #?(:clj (Exception. (str "No match in new-individual for " op))
:cljs (js/Error
(str "No match in new-individual for " op))))))})
```
4. When running a problem, specify the genetic operator in `:variation`.
For example:
```
lein run -m propeller.problems.simple-regression :variation "{:new-genetic-operator 1.0}"
```
## Selection Genetic Operators
1. Go to `propeller.selection.cljc`
2. Define a genetic operator function
3. In `propeller.selection.cljc`, add the new genetic operator in the `select-parent` function under the `case` call.
```clojure
(defn select-parent
"Selects a parent from the population using the specified method."
[pop argmap]
(case (:parent-selection argmap)
...
:new-genetic-operator (:new-genetic-operator )
...
))
```
4. When running a problem, specify the selection method in `:parent-selection`
For example:
```
lein run -m propeller.problems.simple-regression :parent-selection :new-genetic-operator
```

View File

@ -0,0 +1,122 @@
# Adding a Problem
In general, a problem file has 3 components: `train-and-test-data`, `instructions`, `error-function`, and `-main`.
1. To add a new problem, you need training and test data. For Problem Synthesis Benchmark Problems (PSB2),
you can fetch datasets using `psb2.core/fetch-examples`.
```clojure
(defn fetch-examples
"Fetches and returns training and test data from a PSB2 problem.
Returns a map of the form {:train training-examples :test testing-examples}
where training-examples and testing-examples are lists of training and test
data. The elements of these lists are maps of the form:
{:input1 first-input :input2 second-input ... :output1 first-output ...}
The training examples will include all hard-coded edge cases included in the suite,
along with enough random cases to include `n-train` cases.
Note that this function loads large datasets and can be slow, 30-120 seconds.
Parameters:
`datasets-directory` - Location of the PSB2 datasets as downloaded from https://zenodo.org/record/4678739
`problem-name` - Name of the PSB2 problem, lowercase and seperated by dashes.
- Ex: indices-of-substring
`n-train` - Number of training cases to return
`n-test` - Number of test cases to return"
[datasets-directory problem-name n-train n-test]
)
```
2. Define the possible Push instructions to be used to create plushys. It should be a non-lazy list of
instructions from `push/instructions`
3. Define an error function that will evaluate plushys and add `:behaviors parsed-outputs`,
`:errors`, and `:total-error` to the individual
4. Define the function `-main` with a map of default arguments.
## Example of a Problem
```clojure
(ns propeller.problems.PSB2.solve-boolean
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ================================
; SOLVE BOOLEAN from PSB2
; Given a string representing a Boolean
; expression consisting of T, F, |, and &, evaluate it and return
; the resulting Boolean.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "solve-boolean" 200 2000))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :char :string :print})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list true false \t \f \& \|))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:boolean))
inputs)
parsed-outputs (map (fn [output]
(try (read-string output)
#?(:clj (catch Exception e 1000.0)
:cljs (catch js/Error. e 1000.0))))
outputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
10000
(if (= correct-output output)
0
1)))
correct-outputs
parsed-outputs)]
(assoc individual
:behaviors parsed-outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))
```

View File

@ -0,0 +1,20 @@
# Adding a Selection Method
1. Define a selection method function in `propeller.selection` that selects an individual from the population
2. Add the selection method in `propeller.selection/select-parent` under the `case` call:
```clojure
(defn select-parent
"Selects a parent from the population using the specified method."
[pop argmap]
(case (:parent-selection argmap)
:new-selection-method (new-selection-method )))
```
3. When runnning a problem, specify the selection method in `:parent-selection`.
For example:
```
lein run -m propeller.problems.simple-regression :parent-selection :new-selection-method"
```

View File

@ -0,0 +1,5 @@
# A Guide to Experimentation
You can use Propeller to run experiments either on
##

View File

@ -1,12 +1,7 @@
# Introduction to Propeller
TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
# Simplification # Simplification
Propeller allows you to automatically simplify plushys by removing instructions that have no impact on the error values
when evaluating the individual on test cases.
To use Propeller's auto-simplification system, simply include the following four command line arguments when running a problem: To use Propeller's auto-simplification system, simply include the following four command line arguments when running a problem:
```clojure ```clojure
@ -16,7 +11,7 @@ Toggle auto-simplification
```clojure ```clojure
:simplification-k 4 :simplification-k 4
``` ```
This is the upper bound for elements deleted from the plushy every step. Every step, a number in $[1, k]$ of elements is deleted from the plushy representation of the solution. This is the upper bound for elements deleted from the plushy every step. Every step, a number in [1, k] of elements is deleted from the plushy representation of the solution.
```clojure ```clojure
:simplification-steps 1000 :simplification-steps 1000
``` ```
@ -24,7 +19,7 @@ Number of simplification steps to perform
```clojure ```clojure
:simplification-verbose? true :simplification-verbose? true
``` ```
whether or not to output simplification info into the output of the evolutionary run. Whether or not to output simplification info into the output of the evolutionary run.
The output with verbose adds the following lines to the output: The output with verbose adds the following lines to the output:
```clojure ```clojure
{:start-plushy-length 42, :k 4} {:start-plushy-length 42, :k 4}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14
doc/doc/codox/Genome.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

106
doc/doc/codox/README.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,551 @@
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 15px;
}
pre, code {
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
font-size: 9pt;
margin: 15px 0;
}
h1 {
font-weight: normal;
font-size: 29px;
margin: 10px 0 2px 0;
padding: 0;
}
h2 {
font-weight: normal;
font-size: 25px;
}
h5.license {
margin: 9px 0 22px 0;
color: #555;
font-weight: normal;
font-size: 12px;
font-style: italic;
}
.document h1, .namespace-index h1 {
font-size: 32px;
margin-top: 12px;
}
#header, #content, .sidebar {
position: fixed;
}
#header {
top: 0;
left: 0;
right: 0;
height: 22px;
color: #f5f5f5;
padding: 5px 7px;
}
#content {
top: 32px;
right: 0;
bottom: 0;
overflow: auto;
background: #fff;
color: #333;
padding: 0 18px;
}
.sidebar {
position: fixed;
top: 32px;
bottom: 0;
overflow: auto;
}
.sidebar.primary {
background: #e2e2e2;
border-right: solid 1px #cccccc;
left: 0;
width: 250px;
}
.sidebar.secondary {
background: #f2f2f2;
border-right: solid 1px #d7d7d7;
left: 251px;
width: 200px;
}
#content.namespace-index, #content.document {
left: 251px;
}
#content.namespace-docs {
left: 452px;
}
#content.document {
padding-bottom: 10%;
}
#header {
background: #3f3f3f;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
z-index: 100;
}
#header h1 {
margin: 0;
padding: 0;
font-size: 18px;
font-weight: lighter;
text-shadow: -1px -1px 0px #333;
}
#header h1 .project-version {
font-weight: normal;
}
.project-version {
padding-left: 0.15em;
}
#header a, .sidebar a {
display: block;
text-decoration: none;
}
#header a {
color: #f5f5f5;
}
.sidebar a {
color: #333;
}
#header h2 {
float: right;
font-size: 9pt;
font-weight: normal;
margin: 4px 3px;
padding: 0;
color: #bbb;
}
#header h2 a {
display: inline;
}
.sidebar h3 {
margin: 0;
padding: 10px 13px 0 13px;
font-size: 19px;
font-weight: lighter;
}
.sidebar h3 a {
color: #444;
}
.sidebar h3.no-link {
color: #636363;
}
.sidebar ul {
padding: 7px 0 6px 0;
margin: 0;
}
.sidebar ul.index-link {
padding-bottom: 4px;
}
.sidebar li {
display: block;
vertical-align: middle;
}
.sidebar li a, .sidebar li .no-link {
border-left: 3px solid transparent;
padding: 0 10px;
white-space: nowrap;
}
.sidebar li .no-link {
display: block;
color: #777;
font-style: italic;
}
.sidebar li .inner {
display: inline-block;
padding-top: 7px;
height: 24px;
}
.sidebar li a, .sidebar li .tree {
height: 31px;
}
.depth-1 .inner { padding-left: 2px; }
.depth-2 .inner { padding-left: 6px; }
.depth-3 .inner { padding-left: 20px; }
.depth-4 .inner { padding-left: 34px; }
.depth-5 .inner { padding-left: 48px; }
.depth-6 .inner { padding-left: 62px; }
.sidebar li .tree {
display: block;
float: left;
position: relative;
top: -10px;
margin: 0 4px 0 0;
padding: 0;
}
.sidebar li.depth-1 .tree {
display: none;
}
.sidebar li .tree .top, .sidebar li .tree .bottom {
display: block;
margin: 0;
padding: 0;
width: 7px;
}
.sidebar li .tree .top {
border-left: 1px solid #aaa;
border-bottom: 1px solid #aaa;
height: 19px;
}
.sidebar li .tree .bottom {
height: 22px;
}
.sidebar li.branch .tree .bottom {
border-left: 1px solid #aaa;
}
.sidebar.primary li.current a {
border-left: 3px solid #a33;
color: #a33;
}
.sidebar.secondary li.current a {
border-left: 3px solid #33a;
color: #33a;
}
.namespace-index h2 {
margin: 30px 0 0 0;
}
.namespace-index h3 {
font-size: 16px;
font-weight: bold;
margin-bottom: 0;
}
.namespace-index .topics {
padding-left: 30px;
margin: 11px 0 0 0;
}
.namespace-index .topics li {
padding: 5px 0;
}
.namespace-docs h3 {
font-size: 18px;
font-weight: bold;
}
.public h3 {
margin: 0;
float: left;
}
.usage {
clear: both;
}
.public {
margin: 0;
border-top: 1px solid #e0e0e0;
padding-top: 14px;
padding-bottom: 6px;
}
.public:last-child {
margin-bottom: 20%;
}
.members .public:last-child {
margin-bottom: 0;
}
.members {
margin: 15px 0;
}
.members h4 {
color: #555;
font-weight: normal;
font-variant: small-caps;
margin: 0 0 5px 0;
}
.members .inner {
padding-top: 5px;
padding-left: 12px;
margin-top: 2px;
margin-left: 7px;
border-left: 1px solid #bbb;
}
#content .members .inner h3 {
font-size: 12pt;
}
.members .public {
border-top: none;
margin-top: 0;
padding-top: 6px;
padding-bottom: 0;
}
.members .public:first-child {
padding-top: 0;
}
h4.type,
h4.dynamic,
h4.added,
h4.deprecated {
float: left;
margin: 3px 10px 15px 0;
font-size: 15px;
font-weight: bold;
font-variant: small-caps;
}
.public h4.type,
.public h4.dynamic,
.public h4.added,
.public h4.deprecated {
font-size: 13px;
font-weight: bold;
margin: 3px 0 0 10px;
}
.members h4.type,
.members h4.added,
.members h4.deprecated {
margin-top: 1px;
}
h4.type {
color: #717171;
}
h4.dynamic {
color: #9933aa;
}
h4.added {
color: #508820;
}
h4.deprecated {
color: #880000;
}
.namespace {
margin-bottom: 30px;
}
.namespace:last-child {
margin-bottom: 10%;
}
.index {
padding: 0;
font-size: 80%;
margin: 15px 0;
line-height: 16px;
}
.index * {
display: inline;
}
.index p {
padding-right: 3px;
}
.index li {
padding-right: 5px;
}
.index ul {
padding-left: 0;
}
.type-sig {
clear: both;
color: #088;
}
.type-sig pre {
padding-top: 10px;
margin: 0;
}
.usage code {
display: block;
color: #008;
margin: 2px 0;
}
.usage code:first-child {
padding-top: 10px;
}
p {
margin: 15px 0;
}
.public p:first-child, .public pre.plaintext {
margin-top: 12px;
}
.doc {
margin: 0 0 26px 0;
clear: both;
}
.public .doc {
margin: 0;
}
.namespace-index .doc {
margin-bottom: 20px;
}
.namespace-index .namespace .doc {
margin-bottom: 10px;
}
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
line-height: 22px;
}
.markdown li {
padding: 2px 0;
}
.markdown h2 {
font-weight: normal;
font-size: 25px;
margin: 30px 0 10px 0;
}
.markdown h3 {
font-weight: normal;
font-size: 20px;
margin: 30px 0 0 0;
}
.markdown h4 {
font-size: 15px;
margin: 22px 0 -4px 0;
}
.doc, .public, .namespace .index {
max-width: 680px;
overflow-x: visible;
}
.markdown pre > code {
display: block;
padding: 10px;
}
.markdown pre > code, .src-link a {
border: 1px solid #e4e4e4;
border-radius: 2px;
}
.markdown code:not(.hljs), .src-link a {
background: #f6f6f6;
}
pre.deps {
display: inline-block;
margin: 0 10px;
border: 1px solid #e4e4e4;
border-radius: 2px;
padding: 10px;
background-color: #f6f6f6;
}
.markdown hr {
border-style: solid;
border-top: none;
color: #ccc;
}
.doc ul, .doc ol {
padding-left: 30px;
}
.doc table {
border-collapse: collapse;
margin: 0 10px;
}
.doc table td, .doc table th {
border: 1px solid #dddddd;
padding: 4px 6px;
}
.doc table th {
background: #f2f2f2;
}
.doc dl {
margin: 0 10px 20px 10px;
}
.doc dl dt {
font-weight: bold;
margin: 0;
padding: 3px 0;
border-bottom: 1px solid #ddd;
}
.doc dl dd {
padding: 5px 0;
margin: 0 0 5px 10px;
}
.doc abbr {
border-bottom: 1px dotted #333;
font-variant: none;
cursor: help;
}
.src-link {
margin-bottom: 15px;
}
.src-link a {
font-size: 70%;
padding: 1px 4px;
text-decoration: none;
color: #5555bb;
}

View File

@ -0,0 +1,97 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

94
doc/doc/codox/index.html Normal file

File diff suppressed because one or more lines are too long

134
doc/doc/codox/intro.html Normal file

File diff suppressed because one or more lines are too long

2
doc/doc/codox/js/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4
doc/doc/codox/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,112 @@
function visibleInParent(element) {
var position = $(element).position().top
return position > -50 && position < ($(element).offsetParent().height() - 50)
}
function hasFragment(link, fragment) {
return $(link).attr("href").indexOf("#" + fragment) != -1
}
function findLinkByFragment(elements, fragment) {
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
}
function scrollToCurrentVarLink(elements) {
var elements = $(elements);
var parent = elements.offsetParent();
if (elements.length == 0) return;
var top = elements.first().position().top;
var bottom = elements.last().position().top + elements.last().height();
if (top >= 0 && bottom <= parent.height()) return;
if (top < 0) {
parent.scrollTop(parent.scrollTop() + top);
}
else if (bottom > parent.height()) {
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
}
}
function setCurrentVarLink() {
$('.secondary a').parent().removeClass('current')
$('.anchor').
filter(function(index) { return visibleInParent(this) }).
each(function(index, element) {
findLinkByFragment(".secondary a", element.id).
parent().
addClass('current')
});
scrollToCurrentVarLink('.secondary .current');
}
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
function scrollPositionId(element) {
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
return 'scroll::' + $(element).attr('id') + '::' + directory
}
function storeScrollPosition(element) {
if (!hasStorage) return;
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
}
function recallScrollPosition(element) {
if (!hasStorage) return;
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
}
function persistScrollPosition(element) {
recallScrollPosition(element)
$(element).scroll(function() { storeScrollPosition(element) })
}
function sidebarContentWidth(element) {
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
return Math.max.apply(Math, widths)
}
function calculateSize(width, snap, margin, minimum) {
if (width == 0) {
return 0
}
else {
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
}
}
function resizeSidebars() {
var primaryWidth = sidebarContentWidth('.primary')
var secondaryWidth = 0
if ($('.secondary').length != 0) {
secondaryWidth = sidebarContentWidth('.secondary')
}
// snap to grid
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
$('.primary').css('width', primaryWidth)
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
if (secondaryWidth > 0) {
$('#content').css('left', primaryWidth + secondaryWidth + 2)
}
else {
$('#content').css('left', primaryWidth + 1)
}
}
$(window).ready(resizeSidebars)
$(window).ready(setCurrentVarLink)
$(window).ready(function() { persistScrollPosition('.primary')})
$(window).ready(function() {
$('#content').scroll(setCurrentVarLink)
$(window).resize(setCurrentVarLink)
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -78,3 +78,27 @@
(first evaluated-pop)) ;elitism maintains the most-fit individual (first evaluated-pop)) ;elitism maintains the most-fit individual
(repeatedly population-size (repeatedly population-size
#(variation/new-individual evaluated-pop argmap)))))))) #(variation/new-individual evaluated-pop argmap))))))))
; This code is defining a function called "gp" (short for genetic programming) that takes in a map of parameters as its argument.
; The map contains keys such as "population-size", "max-generations", "error-function", "instructions", "max-initial-plushy-size",
; "solution-error-threshold", and "mapper", with default values specified for some of them.
;
;The function starts by printing some information about the starting arguments using
; the prn function and then uses a loop to iterate over generations.
; On each iteration, it creates a population of random plushies using a mapper
; function and genome/make-random-plushy function,
; then it sorts the population by the total error using the error-function
; and sort-by function. It then takes the best individual from the sorted population,
; and if the parent selection is set to epsilon-lexicase, it adds the epsilons to the argmap.
;
;The function then checks if the custom-report argument is set,
; if so it calls that function passing the evaluated population,
; current generation and argmap. If not, it calls the report function
; passing the evaluated population, current generation and argmap.
;
;Then, it checks if the total error of the best individual is less than or equal
; to the solution-error-threshold or if the current generation is greater than or
; equal to the max-generations specified. If either is true, the function
; exits with the best individual or nil. If not, it creates new individuals
; for the next generation using the variation/new-individual function and the
; repeatedly function, and then continues to the next iteration of the loop.

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.basement (ns propeller.problems.PSB2.basement
"=========== PROBLEM DESCRIPTION ============================
BASEMENT from PSB2
Given a vector of integers, return the first
index such that the sum of all integers from the start of the
vector to that index (inclusive) is negative.
Source: https://arxiv.org/pdf/2106.06086.pdf
==============================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,21 +17,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ============================
; BASEMENT from PSB2
; Given a vector of integers, return the first
; index such that the sum of all integers from the start of the
; vector to that index (inclusive) is negative.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "basement" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "basement" 200 2000))
; Random integer between -100 and 100 (from smallest) (defn random-int
(defn random-int [] (- (rand-int 201) 100)) "Random integer between -100 and 100 (from smallest)"
[] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -36,6 +37,10 @@
(list random-int -1 0 1 [])))) (list random-int -1 0 1 []))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,14 @@
(ns propeller.problems.PSB2.bouncing-balls (ns propeller.problems.PSB2.bouncing-balls
" =========== PROBLEM DESCRIPTION ===============================
BOUNCING BALLS from PSB2
Given a starting height and a height after the first bounce of a
dropped ball, calculate the bounciness index
(height of first bounce / starting height). Then, given a number
of bounces, use the bounciness index to calculate the total
distance that the ball travels across those bounces.
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,16 +19,6 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ===============================
; BOUNCING BALLS from PSB2
; Given a starting height and a height after the first bounce of a
; dropped ball, calculate the bounciness index
; (height of first bounce / starting height). Then, given a number
; of bounces, use the bounciness index to calculate the total
; distance that the ball travels across those bounces.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "bouncing-balls" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "bouncing-balls" 200 2000))
@ -33,6 +33,7 @@
(get i :output1)) (get i :output1))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -45,6 +46,10 @@
(list 0.0 1.0 2.0)))) (list 0.0 1.0 2.0))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the FLOAT stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.bowling (ns propeller.problems.PSB2.bowling
"=========== PROBLEM DESCRIPTION ======================
BOWLING from PSB2
Given a string representing the individual
bowls in a 10-frame round of 10 pin bowling, return the
score of that round.
Source: https://arxiv.org/pdf/2106.06086.pdf
========================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,20 +17,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ======================
; BOWLING from PSB2
; Given a string representing the individual
; bowls in a 10-frame round of 10 pin bowling, return the
; score of that round.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; =========================================================
(def train-and-test-data (psb2/fetch-examples "data" "bowling" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "bowling" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Returns random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -35,6 +37,10 @@
(list \- \X \/ \1 \2 \3 \4 \5 \6 \7 \8 \9 10 random-int)))) (list \- \X \/ \1 \2 \3 \4 \5 \6 \7 \8 \9 10 random-int))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,13 @@
(ns propeller.problems.PSB2.camel-case (ns propeller.problems.PSB2.camel-case
"=========== PROBLEM DESCRIPTION =====================================
CAMEL CASE from PSB2
Take a string in kebab-case and convert all of the words to camelCase.
Each group of words to convert is delimited by \"-\", and each grouping
is separated by a space. For example: \"camel-case example-test-string\"
→ \"camelCase exampleTestString\"
Source: https://arxiv.org/pdf/2106.06086.pdf
======================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,25 +18,18 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =====================================
; CAMEL CASE from PSB2
; Take a string in kebab-case and convert all of the words to camelCase.
; Each group of words to convert is delimited by "-", and each grouping
; is separated by a space. For example: "camel-case example-test-string"
; → "camelCase exampleTestString"
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; =======================================================================
(def train-and-test-data (psb2/fetch-examples "data" "camel-case" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "camel-case" 200 2000))
; Visible character ERC ; Visible character ERC
(defn random-char (defn random-char
"Return visible character ERC"
[] []
(rand-nth (map char (range 97 122)))) (rand-nth (map char (range 97 122))))
; Word generator for string ERC ; Word generator for string ERC
(defn word-generator (defn word-generator
"Word generator for string ERC"
[] []
(let [chars-between #(map char (range (int %1) (inc (int %2)))) (let [chars-between #(map char (range (int %1) (inc (int %2))))
chars (chars-between \a \z) chars (chars-between \a \z)
@ -35,6 +37,7 @@
(apply str (repeatedly word-len #(rand-nth chars))))) (apply str (repeatedly word-len #(rand-nth chars)))))
(defn cleanup-length (defn cleanup-length
"Remove spaces and dashes from end of string"
[string len] [string len]
(let [result (take len string)] (let [result (take len string)]
(if (or (= (last result) \space) (if (or (= (last result) \space)
@ -44,6 +47,7 @@
; String ERC ; String ERC
(defn random-input (defn random-input
"Returns random string ERCs"
[len] [len]
(loop [result-string (word-generator)] (loop [result-string (word-generator)]
(if (>= (count result-string) len) (if (>= (count result-string) len)
@ -53,6 +57,7 @@
(word-generator)))))) (word-generator))))))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -66,6 +71,10 @@
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.dice-game (ns propeller.problems.PSB2.dice-game
"=========== PROBLEM DESCRIPTION ===============================
DICE GAME from PSB2
Peter has an n sided die and Colin has an m
sided die. If they both roll their dice at the same time, return
the probability that Peter rolls strictly higher than Colin.
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,14 +17,6 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ===============================
; DICE GAME from PSB2
; Peter has an n sided die and Colin has an m
; sided die. If they both roll their dice at the same time, return
; the probability that Peter rolls strictly higher than Colin.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "dice-game" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "dice-game" 200 2000))
@ -31,6 +31,7 @@
(get i :output1)) (get i :output1))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -43,6 +44,10 @@
(list 0.0 1.0)))) (list 0.0 1.0))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the FLOAT stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,13 @@
(ns propeller.problems.PSB2.fizz-buzz (ns propeller.problems.PSB2.fizz-buzz
"=========== PROBLEM DESCRIPTION =========================
FIZZ BUZZ from PSB2
Given an integer x, return \"Fizz\" if x is
divisible by 3, \"Buzz\" if x is divisible by 5, \"FizzBuzz\" if x
is divisible by 3 and 5, and a string version of x if none of
the above hold.
Source: https://arxiv.org/pdf/2106.06086.pdf
============================================================"
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,19 +18,10 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; FIZZ BUZZ from PSB2
; Given an integer x, return "Fizz" if x is
; divisible by 3, "Buzz" if x is divisible by 5, "FizzBuzz" if x
; is divisible by 3 and 5, and a string version of x if none of
; the above hold.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "fizz-buzz" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "fizz-buzz" 200 2000))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -34,6 +34,10 @@
(list "Fizz" "Buzz" "FizzBuzz" 0 3 5)))) (list "Fizz" "Buzz" "FizzBuzz" 0 3 5))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,13 @@
(ns propeller.problems.PSB2.fuel-cost (ns propeller.problems.PSB2.fuel-cost
"=========== PROBLEM DESCRIPTION =========================
FUEL COST from PSB2
Given a vector of positive integers, divide
each by 3, round the result down to the nearest integer, and
subtract 2. Return the sum of all of the new integers in the
vector
Source: https://arxiv.org/pdf/2106.06086.pdf
============================================================"
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,22 +18,13 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; FUEL COST from PSB2
; Given a vector of positive integers, divide
; each by 3, round the result down to the nearest integer, and
; subtract 2. Return the sum of all of the new integers in the
; vector
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "fuel-cost" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "fuel-cost" 200 2000))
; Random integer between -100 and 100 (from smallest) ; Random integer between -100 and 100 (from smallest)
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -37,6 +37,10 @@
(list random-int 0 1 2 3)))) (list random-int 0 1 2 3))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,11 @@
(ns propeller.problems.PSB2.gcd (ns propeller.problems.PSB2.gcd
"=========== PROBLEM DESCRIPTION ===============================
GCD [GREATEST COMMON DIVISOR] from PSB2
Given two integers, return the largest integer that divides each
of the integers evenly
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,17 +16,9 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ===============================
; GCD [GREATEST COMMON DIVISOR] from PSB2
; Given two integers, return the largest integer that divides each
; of the integers evenly
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(defn map-vals-input (defn map-vals-input
"Returns all the input values of a map" "Returns all the input values of a map"
@ -32,6 +31,7 @@
(get i :output1)) (get i :output1))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -44,6 +44,10 @@
(list random-int)))) (list random-int))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,14 @@
(ns propeller.problems.PSB2.luhn (ns propeller.problems.PSB2.luhn
"=========== PROBLEM DESCRIPTION ============================
LUHN from PSB2
Given a vector of 16 digits, implement Luhns
algorithm to verify a credit card number, such that it follows
the following rules: double every other digit starting with
the second digit. If any of the results are over 9, subtract 9
from them. Return the sum of all of the new digits.
Source: https://arxiv.org/pdf/2106.06086.pdf
==============================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,23 +19,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ============================
; LUHN from PSB2
; Given a vector of 16 digits, implement Luhns
; algorithm to verify a credit card number, such that it follows
; the following rules: double every other digit starting with
; the second digit. If any of the results are over 9, subtract 9
; from them. Return the sum of all of the new digits.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "luhn" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "luhn" 200 2000))
; Random integer between -100 and 100 (from smallest) ; Random integer between -100 and 100 (from smallest)
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -38,6 +39,10 @@
(list 0 2 9 10 random-int)))) (list 0 2 9 10 random-int))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.middle-character (ns propeller.problems.PSB2.middle-character
"=========== PROBLEM DESCRIPTION =============================
MIDDLE CHARACTER from PSB2
Given a string, return the middle
character as a string if it is odd length; return the two middle
characters as a string if it is even length.
Source: https://arxiv.org/pdf/2106.06086.pdf
==============================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,20 +17,12 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =============================
; MIDDLE CHARACTER from PSB2
; Given a string, return the middle
; character as a string if it is odd length; return the two middle
; characters as a string if it is even length.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "middle-character" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "middle-character" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -35,6 +35,10 @@
(list "" 0 1 2 random-int)))) (list "" 0 1 2 random-int))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,11 @@
(ns propeller.problems.PSB2.paired-digits (ns propeller.problems.PSB2.paired-digits
"=========== PROBLEM DESCRIPTION =============================
PAIRED DIGITS from PSB2
Given a string of digits, return the sum
of the digits whose following digit is the same.
Source: https://arxiv.org/pdf/2106.06086.pdf
==============================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,21 +16,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =============================
; PAIRED DIGITS from PSB2
; Given a string of digits, return the sum
; of the digits whose following digit is the same.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "paired-digits" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "paired-digits" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(defn random-char [] (rand-nth '(\0 \1 \2 \3 \4 \5 \6 \7 \8 \9))) (defn random-char "Random character of 0-9" [] (rand-nth '(\0 \1 \2 \3 \4 \5 \6 \7 \8 \9)))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -36,6 +36,10 @@
(list 0 random-int random-char)))) (list 0 random-int random-char))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the INTEGER stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.shopping-list (ns propeller.problems.PSB2.shopping-list
"=========== PROBLEM DESCRIPTION ===============================
DICE GAME from PSB2
Peter has an n sided die and Colin has an m
sided die. If they both roll their dice at the same time, return
the probability that Peter rolls strictly higher than Colin.
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,18 +17,10 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ===============================
; DICE GAME from PSB2
; Peter has an n sided die and Colin has an m
; sided die. If they both roll their dice at the same time, return
; the probability that Peter rolls strictly higher than Colin.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "shopping-list" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "shopping-list" 200 2000))
(defn random-float [] (- (rand 201) 100)) (defn random-float "Random float between -100 and 100" [] (- (rand 201) 100))
(defn map-vals-input (defn map-vals-input
"Returns all the input values of a map" "Returns all the input values of a map"
@ -33,6 +33,7 @@
(get i :output1)) (get i :output1))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -45,6 +46,10 @@
(list 0.0 100.0 random-float)))) (list 0.0 100.0 random-float))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the FLOAT stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,16 @@
(ns propeller.problems.PSB2.snow-day (ns propeller.problems.PSB2.snow-day
"=========== PROBLEM DESCRIPTION ===============================
SNOW DAY from PSB2
Given an integer representing a number
of hours and 3 floats representing how much snow is on the
ground, the rate of snow fall, and the proportion of snow
melting per hour, return the amount of snow on the ground
after the amount of hours given. Each hour is considered a
discrete event of adding snow and then melting, not a continuous
process.
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,19 +21,6 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ===============================
; SNOW DAY from PSB2
; Given an integer representing a number
; of hours and 3 floats representing how much snow is on the
; ground, the rate of snow fall, and the proportion of snow
; melting per hour, return the amount of snow on the ground
; after the amount of hours given. Each hour is considered a
; discrete event of adding snow and then melting, not a continuous
; process.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "snow-day" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "snow-day" 200 2000))
(defn map-vals-input (defn map-vals-input
@ -35,6 +34,7 @@
(get i :output1)) (get i :output1))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -47,6 +47,10 @@
(list 0 1 -1 0.0 1.0 -1.0)))) (list 0 1 -1 0.0 1.0 -1.0))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the FLOAT stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.solve-boolean (ns propeller.problems.PSB2.solve-boolean
"=========== PROBLEM DESCRIPTION ================================
SOLVE BOOLEAN from PSB2
Given a string representing a Boolean
expression consisting of T, F, |, and &, evaluate it and return
the resulting Boolean.
Source: https://arxiv.org/pdf/2106.06086.pdf
=================================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -8,18 +16,11 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ================================
; SOLVE BOOLEAN from PSB2
; Given a string representing a Boolean
; expression consisting of T, F, |, and &, evaluate it and return
; the resulting Boolean.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "solve-boolean" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "solve-boolean" 200 2000))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -32,6 +33,10 @@
(list true false \t \f \& \|)))) (list true false \t \f \& \|))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the BOOLEAN stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,12 @@
(ns propeller.problems.PSB2.spin-words (ns propeller.problems.PSB2.spin-words
"=========== PROBLEM DESCRIPTION ==============================
SPIN WORDS from PSB2
Given a string of one or more words
(separated by spaces), reverse all of the words that are five
or more letters long and return the resulting string.
Source: https://arxiv.org/pdf/2106.06086.pdf
================================================================"
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,25 +17,18 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION ==============================
; SPIN WORDS from PSB2
; Given a string of one or more words
; (separated by spaces), reverse all of the words that are five
; or more letters long and return the resulting string.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ================================================================
(def train-and-test-data (psb2/fetch-examples "data" "spin-words" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "spin-words" 200 2000))
; Visible character ERC ; Visible character ERC
(defn random-char (defn random-char
"Generates random character"
[] []
(rand-nth (map char (range 97 122)))) (rand-nth (map char (range 97 122))))
; random word generator for ERC ; random word generator for ERC
; from https://github.com/thelmuth/Clojush/blob/psb2/src/clojush/problems/psb2/spin_words.clj ; from https://github.com/thelmuth/Clojush/blob/psb2/src/clojush/problems/psb2/spin_words.clj
(defn word-generator (defn word-generator
"Random word generator for ERC from https://github.com/thelmuth/Clojush/blob/psb2/src/clojush/problems/psb2/spin_words.clj"
[] []
(let [word-len (inc (rand-int (if (< (rand) 0.8) (let [word-len (inc (rand-int (if (< (rand) 0.8)
8 8
@ -50,6 +51,7 @@
(apply str (butlast words))))) (apply str (butlast words)))))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -62,6 +64,10 @@
(list 4 5 \space random-char (fn [] (random-input (rand-int 21))))))) (list 4 5 \space random-char (fn [] (random-input (rand-int 21)))))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,11 @@
(ns propeller.problems.PSB2.square-digits (ns propeller.problems.PSB2.square-digits
"=========== PROBLEM DESCRIPTION =========================
SQUARE DIGITS from PSB2
Given a positive integer, square each
digit and concatenate the squares into a returned string.
Source: https://arxiv.org/pdf/2106.06086.pdf
============================================================"
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,19 +16,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; SQUARE DIGITS from PSB2
; Given a positive integer, square each
; digit and concatenate the squares into a returned string.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "square-digits" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "square-digits" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -34,6 +36,10 @@
(list "" 0 1 2 random-int)))) (list "" 0 1 2 random-int))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,14 @@
(ns propeller.problems.PSB2.substitution-cipher (ns propeller.problems.PSB2.substitution-cipher
"=========== PROBLEM DESCRIPTION =========================
SUBSTITUTION CIPHER from PSB2
This problem gives 3 strings.
The first two represent a cipher, mapping each character in
one string to the one at the same index in the other string.
The program must apply this cipher to the third string and
return the deciphered message.
Source: https://arxiv.org/pdf/2106.06086.pdf
============================================================"
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,17 +19,6 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; SUBSTITUTION CIPHER from PSB2
; This problem gives 3 strings.
; The first two represent a cipher, mapping each character in
; one string to the one at the same index in the other string.
; The program must apply this cipher to the third string and
; return the deciphered message.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "substitution-cipher" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "substitution-cipher" 200 2000))
(defn map-vals-input (defn map-vals-input
@ -33,6 +32,7 @@
(vals (select-keys i [:output1]))) (vals (select-keys i [:output1])))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -45,6 +45,10 @@
(list 0 "")))) (list 0 ""))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data) inputs (map (fn [i] (map-vals-input i)) data)

View File

@ -1,4 +1,15 @@
(ns propeller.problems.PSB2.twitter (ns propeller.problems.PSB2.twitter
"=========== PROBLEM DESCRIPTION =============================
TWITTER from PSB2
Given a string representing a tweet, validate whether the tweet
meets Twitters original character requirements. If the tweet
has more than 140 characters, return the string \"Too many characters\".
If the tweet is empty, return the string \"You didnt type anything\".
Otherwise, return \"Your tweet has X characters\", where
the X is the number of characters in the tweet.
Source: https://arxiv.org/pdf/2106.06086.pdf
==============================================================="
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
@ -9,23 +20,14 @@
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =============================
; TWITTER from PSB2
; Given a string representing a tweet, validate whether the tweet
; meets Twitters original character requirements. If the tweet
; has more than 140 characters, return the string "Too many characters".
; If the tweet is empty, return the string "You didnt type anything".
; Otherwise, return "Your tweet has X characters", where
; the X is the number of characters in the tweet.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "twitter" 200 2000)) (def train-and-test-data (psb2/fetch-examples "data" "twitter" 200 2000))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(utils/not-lazy (utils/not-lazy
(concat (concat
;;; stack-specific instructions ;;; stack-specific instructions
@ -38,6 +40,10 @@
(list 0 140 "Too many characters" "You didn't type anything" "your tweet has " " characters")))) (list 0 140 "Too many characters" "You didn't type anything" "your tweet has " " characters"))))
(defn error-function (defn error-function
"Finds the behaviors and errors of an individual: Error is 0 if the value and
the program's selected behavior match, or 1 if they differ, or 1000000 if no
behavior is produced. The behavior is here defined as the final top item on
the STRING stack."
[argmap data individual] [argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap) (let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data) inputs (map (fn [i] (get i :input1)) data)

View File

@ -1,4 +1,8 @@
(ns propeller.problems.simple-regression (ns propeller.problems.simple-regression
"=========== PROBLEM DESCRIPTION =============================
Simple Regression:
Given inputs and outputs, find the target function.
==============================================================="
(:require [propeller.genome :as genome] (:require [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -18,6 +22,7 @@
:test (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) test-inputs)})) :test (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) test-inputs)}))
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(list :in1 (list :in1
:integer_add :integer_add
:integer_subtract :integer_subtract

View File

@ -1,16 +1,19 @@
(ns propeller.problems.string-classification (ns propeller.problems.string-classification
"=========== PROBLEM DESCRIPTION =============================
String Classification:
Given a string, return true if it contains A, C, G, and T. Else return false.
==============================================================="
(:require [propeller.genome :as genome] (:require [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.push.state :as state] [propeller.push.state :as state]
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
;; =============================================================================
;; String classification
;; =============================================================================
;; Set of original propel instructions ;; Set of original propel instructions
(def instructions (def instructions
"stack-specific instructions, input instructions, close, and constants"
(list :in1 (list :in1
:integer_add :integer_add
:integer_subtract :integer_subtract

View File

@ -1,4 +1,6 @@
(ns propeller.problems.valiant (ns propeller.problems.valiant
"Possibly impossible to solve with genetic programming. Stems from the work of Leslie Valiant and involves
determining the parity of an unknown subsequence of a larger sequence of bits."
(:require [propeller.genome :as genome] (:require [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.push.state :as state] [propeller.push.state :as state]