Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
1c0805169f
@ -0,0 +1,24 @@
|
|||||||
|
{:input1 1, :output1 "1"}
|
||||||
|
{:input1 2, :output1 "2"}
|
||||||
|
{:input1 3, :output1 "Fizz"}
|
||||||
|
{:input1 4, :output1 "4"}
|
||||||
|
{:input1 5, :output1 "Buzz"}
|
||||||
|
{:input1 6, :output1 "Fizz"}
|
||||||
|
{:input1 7, :output1 "7"}
|
||||||
|
{:input1 8, :output1 "8"}
|
||||||
|
{:input1 9, :output1 "Fizz"}
|
||||||
|
{:input1 10, :output1 "Buzz"}
|
||||||
|
{:input1 11, :output1 "11"}
|
||||||
|
{:input1 12, :output1 "Fizz"}
|
||||||
|
{:input1 13, :output1 "13"}
|
||||||
|
{:input1 14, :output1 "14"}
|
||||||
|
{:input1 15, :output1 "FizzBuzz"}
|
||||||
|
{:input1 16, :output1 "16"}
|
||||||
|
{:input1 17, :output1 "17"}
|
||||||
|
{:input1 18, :output1 "Fizz"}
|
||||||
|
{:input1 19, :output1 "19"}
|
||||||
|
{:input1 20, :output1 "Buzz"}
|
||||||
|
{:input1 49995, :output1 "FizzBuzz"}
|
||||||
|
{:input1 49998, :output1 "Fizz"}
|
||||||
|
{:input1 49999, :output1 "49999"}
|
||||||
|
{:input1 50000, :output1 "Buzz"}
|
1000000
PSB2/directory/path/goes/here/datasets/fizz-buzz/fizz-buzz-random.edn
Normal file
1000000
PSB2/directory/path/goes/here/datasets/fizz-buzz/fizz-buzz-random.edn
Normal file
File diff suppressed because it is too large
Load Diff
39
README.md
39
README.md
@ -2,12 +2,27 @@
|
|||||||
|
|
||||||
Yet another Push-based genetic programming system in Clojure.
|
Yet another Push-based genetic programming system in Clojure.
|
||||||
|
|
||||||
|
Full documentation is on the GitHub pages link.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
If you have installed [leiningen](https://leiningen.org), which is a tool
|
If you are working in a Clojure IDE with an integrated REPL, the first
|
||||||
for running Clojure programs, then you can run Propeller on a genetic
|
thing you may want to do is to open `src/propeller/session.cljc` and
|
||||||
programming problem that is defined within this project from the command
|
evaluate the namespace declaration and the commented-out expressions
|
||||||
line with the command `lein run -m <namespace>`, replacing `<namespace>`
|
therein. These demonstrate core components of Propeller including
|
||||||
|
complete genetic programming runs.
|
||||||
|
|
||||||
|
To run Propeller from the command line, on a genetic programming problem
|
||||||
|
that is defined within this project, you will probably want to use either
|
||||||
|
the Clojure [CLI tools](https://clojure.org/guides/deps_and_cli) or
|
||||||
|
[leiningen](https://leiningen.org).
|
||||||
|
|
||||||
|
The instructions below are written for leiningen. If you are using
|
||||||
|
the CLI tools instead, then replace `lein run -m` in each command
|
||||||
|
with `clj -M -m`.
|
||||||
|
|
||||||
|
If you are using leiningen, then you can start a run with the command
|
||||||
|
`lein run -m <namespace>`, replacing `<namespace>`
|
||||||
with the actual namespace that you will find at the top of the problem file.
|
with the actual namespace that you will find at the top of the problem file.
|
||||||
|
|
||||||
For example, you can run the simple-regression genetic programming problem with:
|
For example, you can run the simple-regression genetic programming problem with:
|
||||||
@ -44,22 +59,6 @@ containing curly brackets that may confuse your shell:
|
|||||||
lein run -m propeller.problems.simple-regression :variation "{:umad 1.0}"
|
lein run -m propeller.problems.simple-regression :variation "{:umad 1.0}"
|
||||||
```
|
```
|
||||||
|
|
||||||
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)`.
|
|
||||||
|
|
||||||
|
|
||||||
## CLJS Usage
|
## CLJS Usage
|
||||||
|
|
||||||
|
8
deps.edn
8
deps.edn
@ -4,4 +4,10 @@
|
|||||||
org.clojure/clojurescript #:mvn{:version "1.9.946"},
|
org.clojure/clojurescript #:mvn{:version "1.9.946"},
|
||||||
org.clojure/test.check #:mvn{:version "1.1.0"},
|
org.clojure/test.check #:mvn{:version "1.1.0"},
|
||||||
net.clojars.schneau/psb2 #:mvn{:version "1.1.0"}},
|
net.clojars.schneau/psb2 #:mvn{:version "1.1.0"}},
|
||||||
:mvn/repos {}}
|
:mvn/repos {}
|
||||||
|
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
|
||||||
|
:exec-fn codox.main/generate-docs
|
||||||
|
:exec-args {:doc-paths ["src/docs_src"]
|
||||||
|
:output-path "docs"
|
||||||
|
:metadata {:doc "FIXME: write docs" :doc/format :markdown}}
|
||||||
|
}}
|
||||||
|
32
doc/intro.md
32
doc/intro.md
@ -1,32 +0,0 @@
|
|||||||
# Introduction to Propeller
|
|
||||||
|
|
||||||
TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Simplification
|
|
||||||
|
|
||||||
To use Propeller's auto-simplification system, simply include the following four command line arguments when running a problem:
|
|
||||||
|
|
||||||
```clojure
|
|
||||||
:simplification? true
|
|
||||||
```
|
|
||||||
Toggle auto-simplification
|
|
||||||
```clojure
|
|
||||||
: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.
|
|
||||||
```clojure
|
|
||||||
:simplification-steps 1000
|
|
||||||
```
|
|
||||||
Number of simplification steps to perform
|
|
||||||
```clojure
|
|
||||||
:simplification-verbose? true
|
|
||||||
```
|
|
||||||
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:
|
|
||||||
```clojure
|
|
||||||
{:start-plushy-length 42, :k 4}
|
|
||||||
{:final-plushy-length 13, :final-plushy (:in1 :in1 :integer_quot :in1 :in1 :exec_dup :in1 :integer_mult close :exec_dup :integer_add 1 :integer_add)}
|
|
||||||
```
|
|
132
docs/A_Guide_To_Propeller.html
Normal file
132
docs/A_Guide_To_Propeller.html
Normal file
File diff suppressed because one or more lines are too long
52
docs/Adding_Genetic_Operators.html
Normal file
52
docs/Adding_Genetic_Operators.html
Normal file
File diff suppressed because one or more lines are too long
117
docs/Adding_Problem.html
Normal file
117
docs/Adding_Problem.html
Normal file
File diff suppressed because one or more lines are too long
18
docs/Adding_Selection_Method.html
Normal file
18
docs/Adding_Selection_Method.html
Normal file
File diff suppressed because one or more lines are too long
142
docs/Additional_Instructions.html
Normal file
142
docs/Additional_Instructions.html
Normal file
File diff suppressed because one or more lines are too long
5
docs/Generating_Documentation.html
Normal file
5
docs/Generating_Documentation.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/Genetic_Programming_Loop.html
Normal file
4
docs/Genetic_Programming_Loop.html
Normal file
File diff suppressed because one or more lines are too long
14
docs/Genome.html
Normal file
14
docs/Genome.html
Normal file
File diff suppressed because one or more lines are too long
134
docs/Intro.html
Normal file
134
docs/Intro.html
Normal file
File diff suppressed because one or more lines are too long
15
docs/Selection.html
Normal file
15
docs/Selection.html
Normal file
File diff suppressed because one or more lines are too long
20
docs/Simplification.html
Normal file
20
docs/Simplification.html
Normal file
File diff suppressed because one or more lines are too long
38
docs/Variation.html
Normal file
38
docs/Variation.html
Normal file
File diff suppressed because one or more lines are too long
551
docs/css/default.css
Normal file
551
docs/css/default.css
Normal 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;
|
||||||
|
}
|
97
docs/css/highlight.css
Normal file
97
docs/css/highlight.css
Normal 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;
|
||||||
|
}
|
49
docs/index.html
Normal file
49
docs/index.html
Normal file
File diff suppressed because one or more lines are too long
2
docs/js/highlight.min.js
vendored
Normal file
2
docs/js/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
docs/js/jquery.min.js
vendored
Normal file
4
docs/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
112
docs/js/page_effects.js
Normal file
112
docs/js/page_effects.js
Normal 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)
|
||||||
|
})
|
4
docs/propeller.core.html
Normal file
4
docs/propeller.core.html
Normal file
File diff suppressed because one or more lines are too long
7
docs/propeller.genome.html
Normal file
7
docs/propeller.genome.html
Normal file
File diff suppressed because one or more lines are too long
9
docs/propeller.gp.html
Normal file
9
docs/propeller.gp.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.basement.html
Normal file
11
docs/propeller.problems.PSB2.basement.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.problems.PSB2.bouncing-balls.html
Normal file
12
docs/propeller.problems.PSB2.bouncing-balls.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.bowling.html
Normal file
11
docs/propeller.problems.PSB2.bowling.html
Normal file
File diff suppressed because one or more lines are too long
14
docs/propeller.problems.PSB2.camel-case.html
Normal file
14
docs/propeller.problems.PSB2.camel-case.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.problems.PSB2.dice-game.html
Normal file
12
docs/propeller.problems.PSB2.dice-game.html
Normal file
File diff suppressed because one or more lines are too long
9
docs/propeller.problems.PSB2.fizz-buzz.html
Normal file
9
docs/propeller.problems.PSB2.fizz-buzz.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.fuel-cost.html
Normal file
11
docs/propeller.problems.PSB2.fuel-cost.html
Normal file
File diff suppressed because one or more lines are too long
13
docs/propeller.problems.PSB2.gcd.html
Normal file
13
docs/propeller.problems.PSB2.gcd.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.luhn.html
Normal file
11
docs/propeller.problems.PSB2.luhn.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.middle-character.html
Normal file
11
docs/propeller.problems.PSB2.middle-character.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.problems.PSB2.paired-digits.html
Normal file
12
docs/propeller.problems.PSB2.paired-digits.html
Normal file
File diff suppressed because one or more lines are too long
13
docs/propeller.problems.PSB2.shopping-list.html
Normal file
13
docs/propeller.problems.PSB2.shopping-list.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.problems.PSB2.snow-day.html
Normal file
12
docs/propeller.problems.PSB2.snow-day.html
Normal file
File diff suppressed because one or more lines are too long
10
docs/propeller.problems.PSB2.solve-boolean.html
Normal file
10
docs/propeller.problems.PSB2.solve-boolean.html
Normal file
File diff suppressed because one or more lines are too long
13
docs/propeller.problems.PSB2.spin-words.html
Normal file
13
docs/propeller.problems.PSB2.spin-words.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB2.square-digits.html
Normal file
11
docs/propeller.problems.PSB2.square-digits.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.problems.PSB2.substitution-cipher.html
Normal file
12
docs/propeller.problems.PSB2.substitution-cipher.html
Normal file
File diff suppressed because one or more lines are too long
10
docs/propeller.problems.PSB2.twitter.html
Normal file
10
docs/propeller.problems.PSB2.twitter.html
Normal file
File diff suppressed because one or more lines are too long
10
docs/propeller.problems.simple-regression.html
Normal file
10
docs/propeller.problems.simple-regression.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/propeller.problems.software.fizz-buzz.html
Normal file
3
docs/propeller.problems.software.fizz-buzz.html
Normal file
File diff suppressed because one or more lines are too long
13
docs/propeller.problems.software.number-io.html
Normal file
13
docs/propeller.problems.software.number-io.html
Normal file
File diff suppressed because one or more lines are too long
15
docs/propeller.problems.software.smallest.html
Normal file
15
docs/propeller.problems.software.smallest.html
Normal file
File diff suppressed because one or more lines are too long
10
docs/propeller.problems.string-classification.html
Normal file
10
docs/propeller.problems.string-classification.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.problems.valiant.html
Normal file
8
docs/propeller.problems.valiant.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/propeller.push.instructions.bool.html
Normal file
4
docs/propeller.push.instructions.bool.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/propeller.push.instructions.character.html
Normal file
4
docs/propeller.push.instructions.character.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/propeller.push.instructions.code.html
Normal file
4
docs/propeller.push.instructions.code.html
Normal file
File diff suppressed because one or more lines are too long
14
docs/propeller.push.instructions.html
Normal file
14
docs/propeller.push.instructions.html
Normal file
File diff suppressed because one or more lines are too long
6
docs/propeller.push.instructions.input-output.html
Normal file
6
docs/propeller.push.instructions.input-output.html
Normal file
File diff suppressed because one or more lines are too long
20
docs/propeller.push.instructions.numeric.html
Normal file
20
docs/propeller.push.instructions.numeric.html
Normal file
File diff suppressed because one or more lines are too long
18
docs/propeller.push.instructions.polymorphic.html
Normal file
18
docs/propeller.push.instructions.polymorphic.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/propeller.push.instructions.string.html
Normal file
4
docs/propeller.push.instructions.string.html
Normal file
File diff suppressed because one or more lines are too long
25
docs/propeller.push.instructions.vector.html
Normal file
25
docs/propeller.push.instructions.vector.html
Normal file
File diff suppressed because one or more lines are too long
6
docs/propeller.push.interpreter.html
Normal file
6
docs/propeller.push.interpreter.html
Normal file
File diff suppressed because one or more lines are too long
15
docs/propeller.push.limits.html
Normal file
15
docs/propeller.push.limits.html
Normal file
File diff suppressed because one or more lines are too long
15
docs/propeller.push.state.html
Normal file
15
docs/propeller.push.state.html
Normal file
File diff suppressed because one or more lines are too long
9
docs/propeller.selection.html
Normal file
9
docs/propeller.selection.html
Normal file
File diff suppressed because one or more lines are too long
4
docs/propeller.session.html
Normal file
4
docs/propeller.session.html
Normal file
File diff suppressed because one or more lines are too long
23
docs/propeller.simplification.html
Normal file
23
docs/propeller.simplification.html
Normal file
File diff suppressed because one or more lines are too long
6
docs/propeller.tools.calculus.html
Normal file
6
docs/propeller.tools.calculus.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.tools.character.html
Normal file
8
docs/propeller.tools.character.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.tools.distributions.html
Normal file
8
docs/propeller.tools.distributions.html
Normal file
File diff suppressed because one or more lines are too long
23
docs/propeller.tools.math.html
Normal file
23
docs/propeller.tools.math.html
Normal file
File diff suppressed because one or more lines are too long
10
docs/propeller.tools.metrics.html
Normal file
10
docs/propeller.tools.metrics.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/propeller.utils.html
Normal file
12
docs/propeller.utils.html
Normal file
File diff suppressed because one or more lines are too long
51
docs/propeller.variation.html
Normal file
51
docs/propeller.variation.html
Normal file
File diff suppressed because one or more lines are too long
@ -11,4 +11,8 @@
|
|||||||
:profiles {:profiling {:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.1"]]}}
|
:profiles {:profiling {:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.1"]]}}
|
||||||
:main ^:skip-aot propeller.core
|
:main ^:skip-aot propeller.core
|
||||||
:repl-options {:init-ns propeller.core}
|
:repl-options {:init-ns propeller.core}
|
||||||
:jvm-opts ^:replace [])
|
:jvm-opts ^:replace []
|
||||||
|
:plugins [[lein-codox "0.10.8"]]
|
||||||
|
:codox {:output-path "docs"
|
||||||
|
:metadata {:doc "FIXME: write docs" :doc/format :markdown}
|
||||||
|
:doc-paths ["src/docs_src"]})
|
||||||
|
73
scripts/FunctionsToMD.py
Normal file
73
scripts/FunctionsToMD.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
# Takes Push instructions defined through (def-instruction and
|
||||||
|
# puts their documentation into a markdown file in docs_src
|
||||||
|
|
||||||
|
import os
|
||||||
|
from mdutils.mdutils import MdUtils
|
||||||
|
mdFile = MdUtils(file_name='src/docs_src/Additional_Instructions')
|
||||||
|
mdFile.new_header(level=1, title='Additional Instructions')
|
||||||
|
os.chdir('..')
|
||||||
|
|
||||||
|
instructionFiles = os.listdir('src/propeller/push/instructions')
|
||||||
|
instructionFiles.remove('vector.cljc')
|
||||||
|
instructionFiles.remove('polymorphic.cljc')
|
||||||
|
print(instructionFiles)
|
||||||
|
|
||||||
|
hasDefInstruction = False
|
||||||
|
for file in instructionFiles:
|
||||||
|
mdFile.new_header(level=1, title=file)
|
||||||
|
try:
|
||||||
|
print(file)
|
||||||
|
|
||||||
|
# opening and reading the file
|
||||||
|
file_read = open('src/propeller/push/instructions/'+file, "r")
|
||||||
|
|
||||||
|
# set search text
|
||||||
|
text = "(def-instruction"
|
||||||
|
|
||||||
|
# reading file content line by line.
|
||||||
|
lines = file_read.readlines()
|
||||||
|
|
||||||
|
# looping through each line in the file
|
||||||
|
# if the line contains "\(def-instruction", go through lines above that line and add
|
||||||
|
# the Clojure comments to a list which is later written into markdown file.
|
||||||
|
for count, line in enumerate(lines):
|
||||||
|
new_list = []
|
||||||
|
# print(line)
|
||||||
|
# print(count)
|
||||||
|
if text in line:
|
||||||
|
hasDefInstruction = True
|
||||||
|
# print(line)
|
||||||
|
mdFile.new_header(level=2, title=lines[count+1].strip())
|
||||||
|
isComment = True
|
||||||
|
inc = 1
|
||||||
|
while isComment:
|
||||||
|
if lines[count-inc].startswith(';;'):
|
||||||
|
new_list.append(lines[count-inc].replace(';', '').strip())
|
||||||
|
# print(lines[count-inc])
|
||||||
|
inc = inc + 1
|
||||||
|
else:
|
||||||
|
isComment = False
|
||||||
|
new_list.reverse()
|
||||||
|
for comment in new_list:
|
||||||
|
mdFile.write(comment+' ')
|
||||||
|
functionInfo = lines[count+1].strip() + lines[count-1].replace(';', '').strip()
|
||||||
|
# print(functionInfo)
|
||||||
|
new_list.append(functionInfo)
|
||||||
|
# closing file after reading
|
||||||
|
file_read.close()
|
||||||
|
|
||||||
|
# the input string doesn't
|
||||||
|
# found in the text file
|
||||||
|
if not hasDefInstruction:
|
||||||
|
print("\n\"" + text + "\" is not found in \"" + file + "\"!")
|
||||||
|
mdFile.new_paragraph('')
|
||||||
|
else:
|
||||||
|
print("There is"+text)
|
||||||
|
|
||||||
|
# entering except block
|
||||||
|
# if input file doesn't exist
|
||||||
|
except:
|
||||||
|
print("\nThe file doesn't exist!")
|
||||||
|
mdFile.new_table_of_contents()
|
||||||
|
mdFile.create_md_file()
|
5
scripts/GenerateDocs.sh
Normal file
5
scripts/GenerateDocs.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
lein codox
|
||||||
|
python3 FunctionsToMD.py
|
||||||
|
python3 HTMLFix.py
|
27
scripts/HTMLFix.py
Normal file
27
scripts/HTMLFix.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
# fixes ordered lists in codox-generated HTML for specific files
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
os.chdir('..')
|
||||||
|
htmlFiles = ['Adding_Genetic_Operators.html', 'Adding_Problem.html', 'Adding_Selection_Method.html']
|
||||||
|
|
||||||
|
|
||||||
|
for file in htmlFiles:
|
||||||
|
|
||||||
|
with open('docs/'+file, 'r') as f:
|
||||||
|
OL = "ol>"
|
||||||
|
countOL = 0
|
||||||
|
newline = []
|
||||||
|
for line in f.readlines():
|
||||||
|
if OL in line:
|
||||||
|
countOL = countOL + 1
|
||||||
|
if countOL != 2 and countOL != 3 and countOL != 6 and countOL != 7:
|
||||||
|
newline.append(line)
|
||||||
|
else:
|
||||||
|
newline.append(line)
|
||||||
|
|
||||||
|
with open('docs/'+file, 'w') as f:
|
||||||
|
for line in newline:
|
||||||
|
f.writelines(line)
|
||||||
|
|
202
src/docs_src/A_Guide_To_Propeller.md
Normal file
202
src/docs_src/A_Guide_To_Propeller.md
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
# A Guide 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 -->
|
||||||
|
* [A Guide to Propeller](#a-guide-to-propeller)
|
||||||
|
* [Overview](#overview)
|
||||||
|
* [What can you do with Propeller?](#what-can-you-do-with-propeller)
|
||||||
|
* [Installation](#installation)
|
||||||
|
* [How do I run Propeller on a problem?](#how-do-i-run-propeller-on-a-problem)
|
||||||
|
* [An Example](#an-example)
|
||||||
|
* [Can you use a REPL?](#can-you-use-a-repl)
|
||||||
|
* [Tutorials](#tutorials)
|
||||||
|
* [Contributing](#contributing)
|
||||||
|
* [License](#license)
|
||||||
|
* [Citation](#citation)
|
||||||
|
* [Contact](#contact)
|
||||||
|
<!-- TOC -->
|
||||||
|
|
||||||
|
### What can you do with Propeller?
|
||||||
|
|
||||||
|
You can evolve a Push program to solve a problem.
|
||||||
|
You can also use the Push interpreter to evaluate Push programs in other projects,
|
||||||
|
for example in agent-based evolutionary simulations in which
|
||||||
|
agents are controlled by evolving Push programs.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
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 --main <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 -m` with `clj --main` to run the same problem.
|
||||||
|
|
||||||
|
A specific example is provided later below.
|
||||||
|
|
||||||
|
## How do I run Propeller on a problem?
|
||||||
|
|
||||||
|
To run Propeller on a problem, 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_Genetic_Operators.md)
|
||||||
|
- [Adding selection methods](Adding_Selection_Method.md)
|
||||||
|
- [Adding a new problem](Adding_Problem.md)
|
||||||
|
- [Generating Documentation](Generating_Documentation.md)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
Propeller provides a way to automatically [generate documentation](Generating_Documentation.md) for any contributions
|
||||||
|
you might make.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
To discuss Propeller, Push, and PushGP, you can join the [Push-Language Discourse](https://discourse.pushlanguage.org/).
|
62
src/docs_src/Adding_Genetic_Operators.md
Normal file
62
src/docs_src/Adding_Genetic_Operators.md
Normal 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
|
||||||
|
|
||||||
|
```
|
||||||
|
|
122
src/docs_src/Adding_Problem.md
Normal file
122
src/docs_src/Adding_Problem.md
Normal 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`, input instructions, close, and constants (including functions that produce constants).
|
||||||
|
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)))
|
||||||
|
|
||||||
|
```
|
20
src/docs_src/Adding_Selection_Method.md
Normal file
20
src/docs_src/Adding_Selection_Method.md
Normal 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"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
151
src/docs_src/Additional_Instructions.md
Normal file
151
src/docs_src/Additional_Instructions.md
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Table of contents
|
||||||
|
=================
|
||||||
|
|
||||||
|
* [Additional Instructions](#additional-instructions)
|
||||||
|
* [input_output.cljc](#input_outputcljc)
|
||||||
|
* [numeric.cljc](#numericcljc)
|
||||||
|
* [string.cljc](#stringcljc)
|
||||||
|
* [character.cljc](#charactercljc)
|
||||||
|
* [bool.cljc](#boolcljc)
|
||||||
|
* [code.cljc](#codecljc)
|
||||||
|
|
||||||
|
# Additional Instructions
|
||||||
|
|
||||||
|
# input_output.cljc
|
||||||
|
|
||||||
|
## :print_newline
|
||||||
|
Prints new line
|
||||||
|
# numeric.cljc
|
||||||
|
|
||||||
|
## :float_cos
|
||||||
|
Pushes the cosine of the top FLOAT
|
||||||
|
## :float_sin
|
||||||
|
Pushes the sine of the top FLOAT
|
||||||
|
## :float_tan
|
||||||
|
Pushes the tangent of the top FLOAT
|
||||||
|
## :float_from_integer
|
||||||
|
Pushes the floating point version of the top INTEGER
|
||||||
|
## :integer_from_float
|
||||||
|
Pushes the result of truncating the top FLOAT towards negative infinity
|
||||||
|
# string.cljc
|
||||||
|
|
||||||
|
## :string_butlast
|
||||||
|
Pushes the butlast of the top STRING (i.e. the string without its last letter)
|
||||||
|
## :string_concat
|
||||||
|
Pushes the concatenation of the top two STRINGs (second + first)
|
||||||
|
## :string_conj_char
|
||||||
|
Pushes the concatenation of the top STRING and the top CHAR (STRING + CHAR)
|
||||||
|
## :string_contains
|
||||||
|
Pushes TRUE if the top STRING is a substring of the second STRING, and FALSE otherwise
|
||||||
|
## :string_contains_char
|
||||||
|
Pushes TRUE if the top CHAR is contained in the top STRING, and FALSE otherwise
|
||||||
|
## :string_drop
|
||||||
|
Pushes the top STRING with n characters dropped, where n is taken from the top of the INTEGER stack
|
||||||
|
## :string_empty_string
|
||||||
|
Pushes TRUE if the top STRING is the empty string
|
||||||
|
## :string_first
|
||||||
|
Pushes the first CHAR of the top STRING
|
||||||
|
## :string_from_boolean
|
||||||
|
Pushes the STRING version of the top BOOLEAN, e.g. "true"
|
||||||
|
## :string_from_char
|
||||||
|
Pushes the STRING version of the top CHAR, e.g. "a"
|
||||||
|
## :string_from_float
|
||||||
|
Pushes the STRING version of the top FLOAT e.g. "2.05"
|
||||||
|
## :string_from_integer
|
||||||
|
Pushes the STRING version of the top INTEGER, e.g. "3"
|
||||||
|
## :string_indexof_char
|
||||||
|
Pushes the index of the top CHAR in the top STRING onto the INTEGER stack. If the top CHAR is not present in the top string, acts as a NOOP
|
||||||
|
## :string_iterate
|
||||||
|
Iterates over the top STRING using code on the EXEC stack
|
||||||
|
## :string_last
|
||||||
|
Pushes the last CHAR of the top STRING. If the string is empty, do nothing
|
||||||
|
## :string_length
|
||||||
|
Pushes the length of the top STRING onto the INTEGER stack
|
||||||
|
## :string_nth
|
||||||
|
Pushes the nth CHAR of the top STRING, where n is taken from the top of the INTEGER stack. If n exceeds the length of the string, it is reduced modulo the length of the string
|
||||||
|
## :string_occurencesof_char
|
||||||
|
Pushes the number of times the top CHAR occurs in the top STRING onto the INTEGER stack
|
||||||
|
## :string_parse_to_chars
|
||||||
|
Splits the top string into substrings of length 1 (i.e. into its component characters) and pushes them back onto the STRING stack in the same order
|
||||||
|
## :string_remove_char
|
||||||
|
Pushes the top STRING, with all occurrences of the top CHAR removed
|
||||||
|
## :string_replace
|
||||||
|
Pushes the third topmost STRING on stack, with all occurences of the second topmost STRING replaced by the top STRING
|
||||||
|
## :string_replace_char
|
||||||
|
Pushes the top STRING, with all occurences of the second topmost CHAR replaced with the top CHAR
|
||||||
|
## :string_replace_first
|
||||||
|
Pushes the third topmost STRING on stack, with the first occurence of the second topmost STRING replaced by the top STRING
|
||||||
|
## :string_replace_first_char
|
||||||
|
Pushes the top STRING, with the first occurence of the second topmost CHAR replaced with the top CHAR
|
||||||
|
## :string_rest
|
||||||
|
Pushes the rest of the top STRING (i.e. the string without its first letter)
|
||||||
|
## :string_reverse
|
||||||
|
Pushes the reverse of the top STRING
|
||||||
|
## :string_set_char
|
||||||
|
Pushes the top STRING, with the letter at index n (where n is taken from the INTEGER stack) replaced with the top CHAR. If n is out of bounds, it is reduced modulo the length of the string
|
||||||
|
## :string_split
|
||||||
|
Splits the top STRING on whitespace, and pushes back the resulting components in the same order
|
||||||
|
## :string_substr
|
||||||
|
Pushes the substring of the top STRING, with beginning and end indices determined by the second topmost and topmost INTEGERs respectively. If an index is out of bounds, the beginning/end of the string is used instead
|
||||||
|
## :string_take
|
||||||
|
Pushes the substring of the top STRING consisting of its first n letters, where n is determined by the top INTEGER
|
||||||
|
# character.cljc
|
||||||
|
|
||||||
|
## :char_is_letter
|
||||||
|
Pushes TRUE onto the BOOLEAN stack if the popped character is a letter
|
||||||
|
## :char_is_digit
|
||||||
|
Pushes TRUE onto the BOOLEAN stack if the popped character is a digit
|
||||||
|
## :char_is_whitespace
|
||||||
|
Pushes TRUE onto the BOOLEAN stack if the popped character is whitespace (newline, space, or tab)
|
||||||
|
## :char_from_float
|
||||||
|
Pops the FLOAT stack, converts the top item to a whole number, and pushes its corresponding ASCII value onto the CHAR stack. Whole numbers larger than 128 will be reduced modulo 128. For instance, 248.45 will result in x being pushed.
|
||||||
|
## :char_from_integer
|
||||||
|
Pops the INTEGER stack and pushes the top element's corresponding ASCII value onto the CHAR stack. Integers larger than 128 will be reduced modulo 128. For instance, 248 will result in x being pushed
|
||||||
|
## :char_all_from_string
|
||||||
|
Pops the STRING stack and pushes the top element's constituent characters onto the CHAR stack, in order. For instance, "hello" will result in the top of the CHAR stack being \h \e \l \l \o
|
||||||
|
# bool.cljc
|
||||||
|
|
||||||
|
## :boolean_and
|
||||||
|
Pushes the logical AND of the top two BOOLEANs
|
||||||
|
## :boolean_or
|
||||||
|
Pushes the logical OR of the top two BOOLEANs
|
||||||
|
## :boolean_not
|
||||||
|
Pushes the logical NOT of the top BOOLEAN
|
||||||
|
## :boolean_xor
|
||||||
|
Pushes the logical XOR of the top two BOOLEAN
|
||||||
|
## :boolean_invert_first_then_and
|
||||||
|
Pushes the logical AND of the top two BOOLEANs, after applying NOT to the first one
|
||||||
|
## :boolean_invert_second_then_and
|
||||||
|
Pushes the logical AND of the top two BOOLEANs, after applying NOT to the second one
|
||||||
|
## :boolean_from_float
|
||||||
|
Pushes FALSE if the top FLOAT is 0.0, and TRUE otherwise
|
||||||
|
## :boolean_from_integer
|
||||||
|
Pushes FALSE if the top INTEGER is 0, and TRUE otherwise
|
||||||
|
# code.cljc
|
||||||
|
|
||||||
|
## :code_append
|
||||||
|
Concatenates the top two instructions on the :code stack and pushes the result back onto the stack
|
||||||
|
## :exec_do_range
|
||||||
|
Executes the top EXEC instruction (i.e. loops) a number of times determined by the top two INTEGERs, while also pushing the loop counter onto the INTEGER stack. The top INTEGER is the "destination index" and the second INTEGER is the "current index". If the integers are equal, then the current index is pushed onto the INTEGER stack and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent execution. If the integers are not equal, then the current index will still be pushed onto the INTEGER stack but two items will be pushed onto the EXEC stack - first a recursive call to :exec_do_range (with the same code and destination index, but with a current index that has been either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that the range is inclusive of both endpoints a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with the loop counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a destination index that is less than the specified current index.
|
||||||
|
## :exec_do_count
|
||||||
|
Executes the top EXEC instruction (i.e. loops) a number of times determined by the top INTEGER, pushing an index (which runs from 0 to one less than the total number of iterations) onto the INTEGER stack prior to each execution of the loop body. If the top INTEGER argument is <= 0, this becomes a NOOP
|
||||||
|
## :exec_do_times
|
||||||
|
Like :exec_do_count, but does not push the loop counter onto the INTEGER stack
|
||||||
|
## :exec_if
|
||||||
|
If the top BOOLEAN is TRUE, removes the the second item on the EXEC stack, leaving the first item to be executed. Otherwise, removes the first item, leaving the second to be executed. Acts as a NOOP unless there are at least two items on the EXEC stack and one item on the BOOLEAN stack
|
||||||
|
## :exec_when
|
||||||
|
If the top BOOLEAN is TRUE, leaves the first item on the EXEC stack to be executed. Otherwise, it removes it. Acts as a NOOP unless there is at least one item on the EXEC stack and one item on the BOOLEAN stack
|
||||||
|
## :exec_while
|
||||||
|
Keeps executing the top instruction on the EXEC stack while the top item on the BOOLEAN stack is true
|
||||||
|
## :exec_do_while
|
||||||
|
Keeps executing the top instruction on the EXEC stack while the top item on the BOOLEAN stack is true. Differs from :exec_while in that it executes the top instruction at least once
|
||||||
|
## :exec_k
|
||||||
|
The "K combinator" - removes the second item on the EXEC stack
|
||||||
|
## :exec_s
|
||||||
|
The "S combinator" - pops 3 items from the EXEC stack, which we will call A, B, and C (with A being the first one popped), and then pushes a list containing B and C back onto the EXEC stack, followed by another instance of C, followed by another instance of A
|
||||||
|
## :exec_y
|
||||||
|
The "Y combinator" - inserts beneath the top item of the EXEC stack a new item of the form "(:exec_y TOP_ITEM)"
|
8
src/docs_src/Generating_Documentation.md
Normal file
8
src/docs_src/Generating_Documentation.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Generating Documentation for Propeller
|
||||||
|
|
||||||
|
To generate documentation with [codox](https://github.com/weavejester/codox), run `scripts/GenerateDocs.sh`in the command line.
|
||||||
|
This will run "lein codox" on the command line to generate first batch of HTMl files.
|
||||||
|
Then, it runs FunctionsToMD to take Push instructions generated by `def-instruction` and spit it out to a Markdown file.
|
||||||
|
Then, it runs HTMLFix to fix the ordered lists in `Adding_Genetic_Operators.md`, `Adding_Problem.md`, and
|
||||||
|
`Adding_Selection_Method.md`.
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
(ns propeller.core
|
(ns ^:no-doc propeller.core
|
||||||
#?(:clj (:gen-class)))
|
#?(:clj (:gen-class)))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
@ -7,4 +7,4 @@
|
|||||||
;; Exception for when no args were passed
|
;; Exception for when no args were passed
|
||||||
(println "To run a genetic programming problem, provide a the problem's")
|
(println "To run a genetic programming problem, provide a the problem's")
|
||||||
(println "namespace as specified in the Propeller README file at")
|
(println "namespace as specified in the Propeller README file at")
|
||||||
(println "https://github.com/lspector/propeller/blob/master/README.md"))
|
(println "https://github.com/lspector/propeller/blob/master/A_Guide_To_Propeller.md"))
|
@ -1,4 +1,7 @@
|
|||||||
(ns propeller.genome
|
(ns propeller.genome
|
||||||
|
"The genetic material in Propeller. A `plushy` is a list of Push instructions that represent a Push program.
|
||||||
|
They hold the genetic material for an `individual`. In the initial population, we create random plushys."
|
||||||
|
{:doc/format :markdown}
|
||||||
(:require [propeller.push.instructions :as instructions]
|
(:require [propeller.push.instructions :as instructions]
|
||||||
[propeller.utils :as utils]))
|
[propeller.utils :as utils]))
|
||||||
|
|
||||||
@ -10,7 +13,12 @@
|
|||||||
#(utils/random-instruction instructions)))
|
#(utils/random-instruction instructions)))
|
||||||
|
|
||||||
(defn plushy->push
|
(defn plushy->push
|
||||||
"Returns the Push program expressed by the given plushy representation."
|
"Returns the Push program expressed by the given plushy representation.
|
||||||
|
|
||||||
|
The function takes in a plushy representation as input and converts it into a Push program by iteratively processing
|
||||||
|
the plushy elements and adding instructions to the push program.
|
||||||
|
It also handles the case where there are open instructions that need to be closed before the end of the program.
|
||||||
|
"
|
||||||
([plushy] (plushy->push plushy {}))
|
([plushy] (plushy->push plushy {}))
|
||||||
([plushy argmap]
|
([plushy argmap]
|
||||||
(let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
|
(let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
(ns propeller.gp
|
(ns propeller.gp
|
||||||
|
"Main genetic programming loop."
|
||||||
(:require [clojure.string]
|
(:require [clojure.string]
|
||||||
[clojure.pprint]
|
[clojure.pprint]
|
||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
@ -35,7 +36,25 @@
|
|||||||
(println)))
|
(println)))
|
||||||
|
|
||||||
(defn gp
|
(defn gp
|
||||||
"Main GP loop."
|
"Main GP loop.
|
||||||
|
|
||||||
|
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. "
|
||||||
[{:keys [population-size max-generations error-function instructions
|
[{:keys [population-size max-generations error-function instructions
|
||||||
max-initial-plushy-size solution-error-threshold mapper ds-parent-rate ds-parent-gens dont-end ids-type downsample?]
|
max-initial-plushy-size solution-error-threshold mapper ds-parent-rate ds-parent-gens dont-end ids-type downsample?]
|
||||||
:or {solution-error-threshold 0.0
|
:or {solution-error-threshold 0.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
(ns propeller.main
|
(ns ^:no-doc propeller.main
|
||||||
(:require [propeller.core :as propeller]))
|
(:require [propeller.core :as propeller]))
|
||||||
|
|
||||||
(defn main! []
|
(defn main! []
|
||||||
|
@ -56,7 +56,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -74,7 +74,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -125,7 +125,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -57,7 +57,9 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
(ns propeller.problems.PSB2.basement
|
(ns propeller.problems.PSB2.basement
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 ============================
|
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "basement" 200 2000))
|
||||||
; 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))
|
(defn random-int
|
||||||
|
"Random integer between -100 and 100 (from smallest)"
|
||||||
; Random integer between -100 and 100 (from smallest)
|
[] (- (rand-int 201) 100))
|
||||||
(defn random-int [] (- (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)
|
||||||
@ -61,7 +66,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
(ns propeller.problems.PSB2.bouncing-balls
|
(ns propeller.problems.PSB2.bouncing-balls
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 +19,8 @@
|
|||||||
[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 "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "bouncing-balls" 200 2000))
|
||||||
|
|
||||||
(defn map-vals-input
|
(defn map-vals-input
|
||||||
"Returns all the input values of a map (specific helper method for bouncing-balls)"
|
"Returns all the input values of a map (specific helper method for bouncing-balls)"
|
||||||
@ -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)
|
||||||
@ -72,7 +77,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
(ns propeller.problems.PSB2.bowling
|
(ns propeller.problems.PSB2.bowling
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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))
|
|
||||||
|
|
||||||
(defn random-int [] (- (rand-int 201) 100))
|
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "bowling" 200 2000))
|
||||||
|
|
||||||
|
(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)
|
||||||
@ -60,7 +66,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
(ns propeller.problems.PSB2.camel-case
|
(ns propeller.problems.PSB2.camel-case
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 "Data taken from https://zenodo.org/record/5084812" (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)
|
||||||
@ -91,7 +100,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
(ns propeller.problems.PSB2.dice-game
|
(ns propeller.problems.PSB2.dice-game
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 +17,8 @@
|
|||||||
[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 "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "dice-game" 200 2000))
|
||||||
|
|
||||||
(defn map-vals-input
|
(defn map-vals-input
|
||||||
"Returns all the input values of a map"
|
"Returns all the input values of a map"
|
||||||
@ -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)
|
||||||
@ -69,7 +74,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
(ns propeller.problems.PSB2.fizz-buzz
|
(ns propeller.problems.PSB2.fizz-buzz
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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]
|
||||||
@ -20,11 +28,14 @@
|
|||||||
; Source: https://arxiv.org/pdf/2106.06086.pdf
|
; 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 "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fizz-buzz" 200 2000))
|
||||||
(def train-data (:train train-and-test-data))
|
(def train-data (:train train-and-test-data))
|
||||||
(def test-data (:test train-and-test-data))
|
(def test-data (:test train-and-test-data))
|
||||||
|
|
||||||
|
|
||||||
(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 +48,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)
|
||||||
@ -63,7 +78,9 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
(ns propeller.problems.PSB2.fuel-cost
|
(ns propeller.problems.PSB2.fuel-cost
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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]
|
||||||
@ -20,14 +29,15 @@
|
|||||||
; Source: https://arxiv.org/pdf/2106.06086.pdf
|
; 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 "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fuel-cost" 200 2000))
|
||||||
(def train-data (:train train-and-test-data))
|
(def train-data (:train train-and-test-data))
|
||||||
(def test-data (:test train-and-test-data))
|
(def test-data (:test train-and-test-data))
|
||||||
|
|
||||||
; 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
|
||||||
@ -40,6 +50,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)
|
||||||
@ -65,7 +79,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
(ns propeller.problems.PSB2.gcd
|
(ns propeller.problems.PSB2.gcd
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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]
|
||||||
@ -10,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 ===============================
|
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "gcd" 200 2000))
|
||||||
; 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))
|
||||||
(def train-data (:train train-and-test-data))
|
(def train-data (:train train-and-test-data))
|
||||||
(def test-data (:test train-and-test-data))
|
(def test-data (:test train-and-test-data))
|
||||||
|
|
||||||
(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"
|
||||||
@ -36,6 +37,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
|
||||||
@ -48,6 +50,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)
|
||||||
@ -74,7 +80,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
(ns propeller.problems.PSB2.luhn
|
(ns propeller.problems.PSB2.luhn
|
||||||
|
"LUHN from PSB2
|
||||||
|
|
||||||
|
Given a vector of 16 digits, implement Luhn’s
|
||||||
|
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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 Luhn’s
|
|
||||||
; 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 "Data taken from https://zenodo.org/record/5084812" (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)
|
||||||
@ -63,7 +68,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
(ns propeller.problems.PSB2.middle-character
|
(ns propeller.problems.PSB2.middle-character
|
||||||
|
"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"
|
||||||
|
{:doc/format :markdown}
|
||||||
(: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 =============================
|
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "middle-character" 200 2000))
|
||||||
; 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))
|
(defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
|
||||||
|
|
||||||
(defn random-int [] (- (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)
|
||||||
@ -60,7 +64,9 @@
|
|||||||
:cljs (apply + errors)))))
|
:cljs (apply + errors)))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"Runs propel-gp, giving it a map of arguments."
|
"Runs the top-level genetic programming function, giving it a map of
|
||||||
|
arguments with defaults that can be overridden from the command line
|
||||||
|
or through a passed map."
|
||||||
[& args]
|
[& args]
|
||||||
(gp/gp
|
(gp/gp
|
||||||
(merge
|
(merge
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user