0

I am trying to work with a compositional tool called OpenMusic, which is a graphical development environment based on common lisp, and it uses something called "rhythm trees". I am trying to create rhythm trees using a set of rules and in OM this tree must have the following structure:

  • A tree is a list with two elements
  • Its first element is a node
  • Its second element is a list of its children (which can also be trees)

Given a tree depth n, an initial single node tree (1) and transformation rules:

  • (1) -> (1 2)
  • (2) -> (1)

It should give:

n = 1 -> (1 (1 2))

kureta
  • 478
  • 4
  • 15
  • 2
    So where's the question? Remember, this is not a code writing service ;) – Daniel Jour Apr 21 '16 at 09:12
  • you are right @Daniel the question is: how can i define this behavior recursively? answer can be plain English, so no code service. I don't have any idea where to start. I don't even need an answer, just a nudge towards the right direction would be more than enough. – kureta Apr 22 '16 at 14:30
  • @kureta Can you try to explain the question a bit better? Maybe add a few examples of function calls, their results and how the result was reached (basically write out the process you want the computer to do). As it is now, at least I can't figure out what it is you want. I mean, you start with `(1)`. That is transformed to `(1 2)` according to the first rule. There is no transformation rule for `(1 2)` so how do you end up with `(1 (1 2))`? Are the atoms in that supposed to be transformed too (but then you would have `((1 2) (1))`)? – jkiiski Apr 22 '16 at 16:22
  • @jkiiski according to my above definition of trees using lists, the rules are applied to nodes. so a single starting node 1 should have two children 1 and 2. This resulting tree (1 at the top with two children 1, 2) is represented as (1 (1 2)). This tree has two end points (leaves) 1 and 2. applying the rules to one gives 1 and 2. applying the rules to 2 gives one. so after this step the tree is (1 ((1 (1 2)) (2 (1)))) – kureta Apr 22 '16 at 16:56
  • https://mitpress.mit.edu/sicp/full-text/book/book.html –  Apr 22 '16 at 17:24
  • Thank you @Rei I guess I'll mark this answered. – kureta Apr 22 '16 at 17:26

1 Answers1

1

Recursive algorithms for trees/lists are typically written with COND. You figure out what the ending conditions are, and put those first. Then handle atoms, and finally iterate over a list by recursively calling the function on its CAR and CDR, and CONS the results to produce the output list. So the basic template is like:

(defun algo (list)
  (cond
    ((end-condition) suitable-end-value)
    ((atom list) (do-something-with-atom list))
    (t (cons (algo (car list)
             (algo (cdr list))))))

In this case this would be something like:

(defun rhythm-tree (n tree)
  (cond ((zerop n) tree)                 ; First end-condition.
        ((null tree) '())                ; Another end-condition.
        ((atom tree)                     ; An atom: transform into...
         (cons tree                      ; a list of the atom itself...
               (list (rhythm-tree (1- n) ; and a list of children.
                                  (case tree
                                    (1 (list 1 2))
                                    (2 (list 1))
                                    (otherwise '()))))))
        ;; Iterate over elements of a list.
        (t (cons (rhythm-tree n (car tree))
                 (rhythm-tree n (cdr tree))))))

(rhythm-tree 1 1)
;=> (1 (1 2))
(rhythm-tree 2 1)
;=> (1 ((1 (1 2)) (2 (1))))
jkiiski
  • 8,206
  • 2
  • 28
  • 44