From a10addcc9e4c1637a5eeba20f181754916422c53 Mon Sep 17 00:00:00 2001 From: Lee Spector Date: Sun, 31 Dec 2023 21:38:49 -0500 Subject: [PATCH] Move opens into instructions/parentheses; implement :auto-close to set probability of adding a close from opens produced by instructions --- src/propeller/genome.cljc | 4 +-- .../push/instructions/parentheses.cljc | 33 +++++++++++++++++++ src/propeller/utils.cljc | 23 +++++++++---- 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 src/propeller/push/instructions/parentheses.cljc diff --git a/src/propeller/genome.cljc b/src/propeller/genome.cljc index 9ca16bc..84ec2df 100755 --- a/src/propeller/genome.cljc +++ b/src/propeller/genome.cljc @@ -2,7 +2,7 @@ "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.parentheses :as parentheses] [propeller.utils :as utils])) (defn make-random-plushy @@ -21,7 +21,7 @@ They hold the genetic material for an `individual`. In the initial population, w [plushy argmap] (let [opener? #(and (vector? %) (= (first %) 'open))] ;; [open ] marks opens (loop [push () ;; iteratively build the Push program from the plushy - plushy (mapcat #(let [n (get instructions/opens %)] + plushy (mapcat #(let [n (get parentheses/opens %)] (if (and n (> n 0)) [% ['open n]] diff --git a/src/propeller/push/instructions/parentheses.cljc b/src/propeller/push/instructions/parentheses.cljc new file mode 100644 index 0000000..8f40fd3 --- /dev/null +++ b/src/propeller/push/instructions/parentheses.cljc @@ -0,0 +1,33 @@ +(ns propeller.push.instructions.parentheses) + +;; Number of blocks opened by instructions (default = 0) +(def opens + "Number of blocks opened by instructions. The default is 0." + {:exec_dup 1 + :exec_dup_times 1 + :exec_dup_items 0 ; explicitly set to 0 to make it clear that this is intended + :exec_eq 0 ; explicitly set to 0 to make it clear that this is intended + :exec_pop 1 + :exec_rot 3 + :exec_shove 1 + :exec_swap 2 + :exec_yank 0 ; explicitly set to 0 to make it clear that this is intended + :exec_yank_dup 0 ; explicitly set to 0 to make it clear that this is intended + :exec_deep_dup 0 ; explicitly set to 0 to make it clear that this is intended + :exec_print 1 + :exec_if 2 + :exec_when 1 + :exec_while 1 + :exec_do_while 1 + :exec_do_range 1 + :exec_do_count 1 + :exec_do_times 1 + :exec_k 2 + :exec_s 3 + :exec_y 1 + :string_iterate 1 + :vector_boolean_iterate 1 + :vector_string_iterate 1 + :vector_integer_iterate 1 + :vector_float_iterate 1 + }) \ No newline at end of file diff --git a/src/propeller/utils.cljc b/src/propeller/utils.cljc index a1fa802..181f4cd 100755 --- a/src/propeller/utils.cljc +++ b/src/propeller/utils.cljc @@ -3,7 +3,8 @@ (:require [clojure.zip :as zip] [clojure.repl :as repl] [propeller.tools.metrics :as metrics] - [propeller.tools.math :as math])) + [propeller.tools.math :as math] + [propeller.push.instructions.parentheses :as parentheses])) (defn filter-by-index "filters a collection by a list of indices" @@ -50,11 +51,21 @@ "Returns a random instruction from a supplied pool of instructions, evaluating ERC-producing functions to a constant literal." [instructions argmap] - (let [instruction (rand-nth instructions)] - (if (fn? instruction) - (instruction) - instruction))) - + (if (:auto-close argmap) + (let [instructions (remove #(= % 'close) instructions) + p (/ (apply + (filter identity + (map #(get parentheses/opens %) instructions))) + (count instructions))] + (if (< (rand) p) + 'close + (let [instruction (rand-nth instructions)] + (if (fn? instruction) + (instruction) + instruction)))) + (let [instruction (rand-nth instructions)] + (if (fn? instruction) + (instruction) + instruction)))) (defn count-points "Returns the number of points in tree, where each atom and each pair of parentheses