(ns nal.deriver.list-expansion (:require [nal.deriver.utils :refer [walk]] [clojure.string :as s])) | |
(def max-elements-in-list 7) | |
Finds the first :list element in the rule. | (defn get-list [prefix statement] (cond (and (keyword? statement) (s/starts-with? (str statement) prefix)) statement (coll? statement) (some identity (map #(get-list prefix %) statement)) :default nil)) |
Generates n symbols with prefix. | (defn gen-symbols [prefix n] (map #(symbol (str prefix (inc %))) (range n))) |
Replaces :list/ with symbols. | (defn replace-list-elemets [statement l list-name n] (walk statement (and (coll? el) (some #{l} el)) (mapcat (fn [e] (if (= l e) (concat '() (gen-symbols list-name n)) (list e))) el))) |
Fetches name of the list. | (defn list-name [l] (->> l str (drop 6) s/join)) |
(defn expand-:from-element "Expands :from/ element in rule, so as a result will be created n rules, in each of them :form/A will be replaced with A1 or A2 or A3, etc." [statement from-name list-name n] (map (fn [idx] (walk statement (= from-name el) (symbol (str list-name idx)))) (range 1 (inc n)))) | |
Expands rules with :list/ elements, as a result will be created 5 rules, where :list/ will be replaced with A1, A1 A2, ..., A1..A5. | (defn generate-all-lists [r] (let [list (get-list ":list" r) l-name (list-name list)] (mapcat #(let [st (replace-list-elemets r list l-name %)] (if-let [from-name (get-list ":from" st)] (expand-:from-element st from-name l-name %) [st])) (range 1 (inc max-elements-in-list))))) |
Checks if rule contains any :list element. | (defn contains-list? [r] (get-list ":list" r)) |