#|
Okay I want to use jmbr's ( @[email protected] ) polynomial rings
from cl-buchberger as lambda definitions
with my note generation.

Edit : I took out the McCLIM dependency stuff.
|#

;;; My note stuff, targetted in lispusers
;; (asdf:oos 'asdf:load-op :lispusers/tfw/high/turntable)

;;; jmbr's
(require :cl-buchberger)

;;; clim backend (not used right now)
;; (require :McCLIM)

;;; Package to play in.
(uiop:define-package music-user
(:mix :cl-buchberger
;;       :clim :clim-lisp :lispusers/tfw/high/turntable
 :cl))
(in-package :music-user)

;;; Not used atm.
#|
(defvar *frame*
(make-application-frame 'turntable
 :note-path #P"~/synthember/008.raw"))
|#
;;; Just leave :base-ring as default
;; (defvar *ring* (make-instance 'polynomial-ring :variables '(x y z)))

;;; Some trivial polynomials.
(defvar *100* (make-polynomial 100))
(defvar *x* (make-polynomial '(expt x 1)))
(defvar *y* (make-polynomial '(expt y 1)))
(defvar *z* (make-polynomial '(expt z 1)))

;;; I found this function so hard to write, seriously, but I feel
;;; like I need it.
;;; It turns a cl-buchberger polynomial into a numerical lamdba form.
;;; Needs to be compiled (evaluated) by the caller.
;;; Note this is a run time thing even though it looks like a macro.
(defun lambdaise (poly)
(let* ((Variables (cl-buchberger::variables
                   (cl-buchberger::base-ring poly)))
       (co-mos
        (flet ((ret-co-mos (term)
                (list (cl-buchberger::coefficient term)
                      (cl-buchberger::monomial term))))
         (mapterm #'ret-co-mo poly)))
       (cos (mapcar 'car co-mos))
       (mos (mapcar 'cadr co-mos)))
 `(lambda (,@variables)
   (+
    ,@(loop for co in cos for mo in mos collect
      `(* ,co
         ,@(loop for m across mo for v in variables collect
             `(expt ,v ,m))))))))

;;; Example of lambdaise returning a lambda that evaluates correctly.
(let ((form
      (lambdaise
       (ring+ (ring* *x* *y* *y*) (ring* *100* *z*) *100*))))
(print `(funcall (eval ,form) 1 2 3))
(print '=)
(print (funcall (eval form) 1 2 3))
(print '=)
(print 404))