Thank you very much Frank, I think I got it.
A follow-up question. With this technique, I have several models, and the data is flowing from one model to the next. Nice.
But is there a suggested procedure to temporarily isolate the model, so that it can be tested by itself? In other words, can one explicitly set values to cells whose initform defines them in terms of other model's slots.
I tried setf on a cell that was linked to another model. It seems to work.
But, is its initform (c? (let ((m (fm^ :other-model))) (blah (slot m) ...))) still active?
How can I test that? By forcing that model to recompute itself. How do I do that? I did not find an obvious candidate in the exported symbols.
Thanks again,
Mirko
... Output of the short demo below:
(m-test)
M1: New value for slot a => 1.
M1: New value for slot b => 1.
M2: New value for slot c => 1.
STEP 1
M1: New value for slot a => 2.
M2: New value for slot c => 2.
STEP 2
M1: New value for slot b => 3.
M2: New value for slot c => 6.
... cute, ha ?
;-)))
Frank
Am 17.04.2012 um 23:08 schrieb Frank Goenninger:
> Hi Mirko,
>
> Am 17.04.2012 um 20:17 schrieb Mirko Vukovic:
>
>> Hello,
>>
>> I am doing very basic cell-stuff, much like the ones in the doc folder: Not liking excel and its cousins, I am implementing spread-sheet like calculations in cells.
>>
>> My question:
>>
>> 1) Can I build two models (model1, model2) and specify that a slot in model2 depends on changes in some other slot in model1?
>
> Sure:
>
> (in-package #:cells)
>
> ;;; ------------------
> ;;; *** Model M1 ***
> ;;; ------------------
>
> (defmd m1 ()
> a
> b
> :a (c-in 1)
> :b (c-in 1))
>
> (defobserver a ((self m1))
> (when new-value
> (format *debug-io* "~%~S: New value for slot a => ~S."
> self (a self))))
>
> (defobserver b ((self m1))
> (when new-value
> (format *debug-io* "~%~S: New value for slot b => ~S."
> self (b self))))
>
> (defmacro mk-m1 (id)
> `(make-instance 'm1
> :fm-parent *parent*
> :md-name ,id))
>
> ;;; ------------------
> ;;; *** Model M2 ***
> ;;; ------------------
>
> (defmd m2 ()
> (c (c? (let ((m1 (fm^ :m1))) ;; -> fm^ searches for :m1 in the current family
> (* (a m1) (b m1))))))
>
> (defmacro mk-m2 (id)
> `(make-instance 'm2
> :fm-parent *parent*
> :md-name ,id))
>
> (defobserver c ((self m2))
> (when new-value
> (format *debug-io* "~%~S: New value for slot c => ~S."
> self (c self))))
>
> ;;; ------------------
> ;;; *** Family M ***
> ;;; ------------------
>
> (defmd m (family)
> (kids (c? (the-kids
> (mk-m1 :m1)
> (mk-m2 :m2)))) ;; :m1 and :m2 are kids of :m's family.
> :md-name :m)
>
> ;;; -----------------
> ;;; *** TESTING ***
> ;;; -----------------
>
> (defun m-test ()
>
> (let* ((self (make-instance 'm))
> (m1 (fm-find-kid self :m1)))
>
> ;; Step 1
> (format *debug-io* "~%~%STEP 1~&")
> (setf (a m1) 2)
> ;; => C = 2
> ;; See observer for C !
>
> ;; Step 2
> (format *debug-io* "~%~%STEP 2 ~&")
> (setf (b m1) 3))
> ;; => C = 6
> ;; See observer for C !
>
> (values))
>
>
>> 2) Related: can I change a slot specification in a model. For example from `c-in' to `c?'. I assume that I can, but I would have to re-initialize the model somehow. Correct?
>
> This one I'd like to leave for Kenny to answer ... Never did that during one run - I always reset cells via #'cells-reset and the started over when I needed to do that.
>
>> I am also very interested in the question posted just a few minutes ago. I would like to build an automated way of generating a GUI front end my cell models.
>
> I tried to answer this in the other mail.
>
>>
>> Thanks,
>>
>> Mirko
>
> Hope that helps.
>
> Cheers
> Frank
>