; FILE: graphics.l
; PURPOSE: Lucid graphics for displaying networks (sg), line graphs (lg)
; and real-time activation graphs (ag).
; PROGRAMMER: Greg Nelson
; CREATED: 7-20-87
; UPDATED: 5-26-88
; UPDATED: 7-22-88 - made DEVOWEL a bit cleaner
; UPDATED: 9-6-88 - additions to function grapher (file labels, ELIMINATE)
; UPDATED: 9-7-88 - corrections to fg file reading functions
; UPDATED: 10-12-88 - fixed the spidergrapher for the new link format

; NEW PURPOSE: Macintosh Allegro graphics for networks and real-time activation
; for MacECHO
; PROGRAMMER (editor): David Gochfeld
; UPDATED: 6-4-90 - began to replace window initialization and drawing with
; Allegro code.
; Replaced *grapher-viewport* with *grapher-window* and
; *grapher-bitmap* with *grapher-grafport* (a "view")
; Macros and fuctions written for clear-bitmap, make-position,
; draw-line and stringblt.
; to 6-6-90
; 6-8-90 - Changed "grapher-window" to "actgraph-window" for
; use in End_ECHO_session in mac_interface.l.
; Began to excise code for circle activation graphs and
; for *acme-mode* from Activation Grapher section.
; Put in more constant for the Activation grapher, to replace
; Greg's magic numbers. See defvar section for activation-
; grapher, below.
; Set size of the view (*grapher-grafport*) to the same as the
; window (*actgraph-window*)
; 6-11-90 - Drawing FIXED: now draws activation graphs correctly into
; *grapher-grafport*.
; Use saving-window object class (from their example, modified
; slightly) to redraw grapher window after it's been covered.
; Don't need *grapher-grafport* -- draw directly into window.
; Now draws text onto bitmap as well as window, so the labels
; are also redrawn when the window is refreshed.
; 6-12-90 - Refresh macro to redraw window from contents of bitmap: used to
; make labels appear in the bitmap font as soon as labels and axes drawn.
; This is a hack, instead of trying to set the bitmap font, which is a
; real mess.
; Added creation of Network graph window, and put actgraph window in
; upper right corner for default.
; Deleted sections for line-grapher and function-grapher. (half the file).
; Changed draw-line to take a window argument -- draw in that window.
; Changed refresh-win to select the window before redrawing it, so it
; doesn't draw its contents over a window in front of it and emss things up.
; 6-13-90 - Network Grapher draws correctly:
; created function draw-circle which calls the Quickdraw oval commands.
; removed some fluff greg had that is no longer needed (particularly
; *second-label* and child-function stuff, and reduced childcnt calculations
; to one place -- draw-around.
; Changed name of kidsfunc to linked-units.
; Made calculations of x-radius and y-radius work in pixels.
; Replaced calls to font-fixed-width with calls to the toolbox routine
; _StringWidth. PROBLEM: may need to be done IN the correct window?
; 6-14-90 - Added mouse control to network grapher:
; *unit-loc-alist* contains the top, bottom, right, and left values at which
; each unit is located, associated with that unit.
; window-click-event-handler
; record-loc converts loc of unit to a rectangle containing unit, and stores
; the rectangle and unit in the alist.
; search-loc looks in alist for unit corresponding to point.
; loc-test is the test used by search-loc to search the alist.
; Links are now drawn in patterns depending on weight: positive is black,
; negative is light grey, and zero is grey.
; 6-15-90 - reset-act now sets *actwin-x*, *actwin-y*, and *graphs-per-line*
; depending on the current size of the window -- so if the window is
; resized before a run, graphs will be printed in it according to its
; new size. Resizing during a run doesn't affect the distribution
; of the graphs.
; 6-18-90 - reset-act now tells you to enter a new list of units to graph OR to
; resize the window if won't fit in the window. Also, show-act
; now checks to make sure the window is open before drawing.
; NOTE: when a window is shrunk, everything off the edge of the window will be lost. So
; users should be warned not to shrink the activation grapher window until done with
; the information printed in it.
; 4-29-98 - port to MCL 4.2 and incorporation with COHERE

 

 

;(in-package 'user)

(require 'quickdraw "Sanders HD:Lisp:MCL 4.2:Library:QuickDraw.pfsl") ; loads quickdraw before loading this
(require 'saving-window "Sanders HD:Lisp:COHERE:Lisp code:window_objects.l") ; creates "saving-window" object class

; General global variables
(defvar *actgraph-window* nil "Name of activation grapher window.")
(defvar *netgraph-window* nil "Name of network grapher window.")
(defvar *grapher-font* nil "Name of the grapher font.")

(defvar *debug* nil "Turn on the debugger.")
(defvar *devowel-length* 30 "Length beyond which vowels will be taken out.")
(defvar *time-step* 0 "Added by Paul.")
(defvar default_activation .01 "This is defined elsewhere.")

 

; Global variables specific to network grapher
(defvar *netwin-height* 6 "Height in inches of grapher window.")
(defvar *netwin-width* 6 "Width in inches of grapher window.")

(defvar *netwin-x* (* *netwin-width* *pixels-per-inch-x*) "Window width.")
(defvar *netwin-y* (* *netwin-height* *pixels-per-inch-y*) "Window height.")
(defvar *netwin-xs* nil "Window starting x position.")
(defvar *netwin-ys* nil "Window starting y position.")
(defvar *unit-location-alist* nil "A-list for relating locations with units, for mouse-selection.")
(defvar *unit-radius* 5 "Default size for unit circles.")
(defvar *nethoriz-spc* nil "X distance between adjacent units.") ; different than spc's for act-grapher
(defvar *netvert-spc* nil "Y distance between adjacent units.")
(defvar *drawing-mode* 'circle "Determines whether to draw circle or squares.")
(defvar *x-radius* nil "X radius of the circle on which units are plotted.")
(defvar *y-radius* nil "Y radius of the circle on which units are plotted.")
(defvar *second-label* 'actstring "Put activation as a second label at each node.")
(defvar *link-labels* 'weight-link-label
"The function to print as label on links, when non-nil.")
(defvar *link-width* 'weight-link-width
"The function which determines widths, when non-nil.")
(defvar *known-functions* nil
"Variable listing which functions can be graphed.")

; Global variables specific to activation grapher
(defvar *act-type* nil "Type of activation graph: 'circle or 'line") ; Don't use this anymore.
(defvar *unit-list* nil "List of units currently being graphed.")
(defvar *act-list* nil "Previous activations of current units.")
(defvar *actwin-height* 4 "Height in inches of grapher window.")
(defvar *actwin-width* 4 "Width in inches of grapher window.")

(defvar *actwin-x* (* *actwin-width* *pixels-per-inch-x*) "Window width.")
(defvar *actwin-y* (* *actwin-height* *pixels-per-inch-y*) "Window height.")
(defvar *actwin-xs* nil "Window starting x position.")
(defvar *actwin-ys* nil "Window starting y position.")

(defvar *graph-hgt* 50 "Height of graph + label + space.")
(defvar *graph-wid* 60 "Width of graph + space.")
(defvar *graphs-per-line* (truncate *actwin-x* *graph-wid*) "Number of graphs per row in window.")
(defvar *vert-spc* 5 "Vertical space between graphs.")
(defvar *horiz-spc* 10 "Horizontal space between graphs.")
(defvar *lbl-hgt* 9 "Height of label")
(defvar *axis-hgt* (- *graph-hgt* (+ *vert-spc* *lbl-hgt*)) "Length of y axis in pixels.")
(defvar *axis-wid* (- *graph-wid* *horiz-spc*) "Length of x axis in pixels.")
(defvar *left-margin* 5 "Margin on left side of window.")
; Set *title-bar-height* to 10 to insure that everything is visible when ; Do I still need this?
; drawing labels above the axes. Otherwise set it to 0.
(defvar *title-bar-height* 0 "Height of title bar at top of window.")
(defvar *top-margin* (+ 0 *title-bar-height*) "Margin on top of window.")

; Should this be translated?
;(defun dumpwin (file)
; (shell (format nil "screendump -x ~a -y ~a -X ~a -Y ~a ~a"
; *winxs* *winys* *winx* *winy* file))
;)

 

; Grapher initialization function
(defun start-graph (&optional (gmode nil) (restart nil)
(hei *actwin-height*) ; Activation grapher is default
(wid *actwin-width*)
(xloc nil)
(yloc nil))
"Function to open a window for the grapher and set the global variables."
(let ((pix-hei (* *pixels-per-inch-y* hei)) ; hei and wid are size in inches
(pix-wid (* *pixels-per-inch-x* wid))) ; convert to pixel sizes.

(cond ((equal gmode 'act) ; the following are specifically for opening the
; activation grapher window
; If no values given for xloc and yloc of window, place window in upper-right corner.
(setq xloc (or xloc (- *screen-width* pix-wid)))
(setq yloc (or yloc *menubar-bottom*))

; Open window if never opened, explicitly requested (restart), or if closed since last run
(cond ((or
(not (null restart))
(null *actgraph-window*)
(not (wptr *actgraph-window*))) ; t if window has been closed
(setq *actgraph-window* (make-instance 'saving-window
:window-title "Activation Grapher"
:view-position (make-point xloc yloc)
:view-size (make-point pix-hei pix-wid)))

(setq *actwin-x* pix-wid) (setq *actwin-y* pix-hei)
(setq *actwin-xs* xloc) (setq *actwin-ys* yloc)

)
)
)

((equal gmode 'network) ; Open the network-grapher window
; If no values given for xloc and yloc of window, place window in lower-right corner.
(setq xloc (or xloc (- *screen-width* pix-wid)))
(setq yloc (or yloc (- *screen-height* pix-hei)))

; Open window if never opened, explicitly requested (restart), or if closed since last run
(cond ((or
(not (null restart))
(null *netgraph-window*)
(not (wptr *netgraph-window*))) ; t if window has been closed
(setq *netgraph-window* (make-instance 'network-window
:window-title "Network Grapher"
:view-position (make-point xloc yloc)
:view-size (make-point pix-hei pix-wid)))

(setq *netwin-x* pix-wid) (setq *netwin-y* pix-hei)
(setq *netwin-xs* xloc) (setq *netwin-ys* yloc)

)
)
(setq *nethoriz-spc* (round (/ pix-wid 5)))
(setq *netvert-spc* 45)
)
)
; (setq *last-init* gmode)
)
)

 

;;;;;;; General macros to translate Lucid sunview commands to Mac Allegro commands ;;;;;;;

(defmacro make-position (x y) `(make-point ,x ,y))

(defmacro draw-line (window pt1 pt2)
`(progn (move-to ,window ,pt1)
(line-to ,window ,pt2)))

(defmacro refresh-win (win)
`(progn (window-select ,win)
(window-draw-contents ,win)))

(defun clear-bitmap (win)
(erase win) ; erase is defined in saving-window.l
)

(defun draw-circle (win cntr radius &optional (highlight nil))
"Draw a circle centered at cntr with radius, filled if highlight is t, empty otherwise."
(let ((left (- (point-h cntr) radius))
(top (- (point-v cntr) radius))
(right (+ (point-h cntr) radius))
(bottom (+ (point-v cntr) radius)))
(cond (highlight
(paint-oval win (make-point left top) (make-point right bottom)))
(t ; Just draw the darn thing, erasing whatever's under it.
(erase-oval win (make-point left top) (make-point right bottom))
(frame-oval win (make-point left top) (make-point right bottom)))
) ; note: all oval functions are defined in saving-window.l and require two points as args.
)
)

 

;;;;;;;;;;;;;;;;;;; Network grapher (sg)

 

 

; This is now in saving-windows.l, as an obfun for the new class network-window
;
;(defobfun (window-click-event-handler *netgraph-window*) (where)
; "Object function to respond to mouse clicks in *netgraph-window*, to allow selection of units."
; (usual-window-click-event-handler where)
; ; Probably what I'm going to need to do here is set up an a-list for each graph,
; ; and associate the locations of each unit in the graph with its coordinates.
; ; Then I'll need to look for the coordinates +/- *unit-radius* in each direction.
; ; Once I've got the unit name, I just clear the window and call (draw-around unit)
;
;; (print (point-string where))
;
; (let ((unit (search-loc where))) ; find unit in which mouse was clicked
; (if unit (draw-around unit)) ; if there is such a unit, draw it's connectivity
; )
;)

 

 

(defun child-count (unit)
"Function to return the number of connections to a given unit."
(length (linked-units unit))
)

(defun x-rel (num childcnt &optional (xcent (round (/ *netwin-x* 2))))
"Calculate x position of a given unit."
(if (equal *drawing-mode* 'circle)
(let (angle)
(setq angle (* num (/ (* 2 pi) childcnt)))
(round (+ xcent (* *x-radius* (cos angle))))
)
; (let (percol delt col ncol) ;this is for the square format: ask Paul if I can trash this option
; ; otherwise I'll have to rewrite this code
; (setq delt (round (/ (bitmap-height *grapher-grafport*)
; (if (< childcnt 16) (+ 2 childcnt) (+ 5 childcnt)))))
; (setq ncol 1) (setq percol childcnt)
; (if (< delt *netvert-spc*) (prog () (setq delt (* delt 2))
; (setq percol (round (/ percol 2.0)))
; (setq ncol (* ncol 2))))
; (if (< delt *netvert-spc*) (prog () (setq delt (round (* delt 2)))
; (setq percol (round (/ percol 2.0)))
; (setq ncol (* ncol 2))))
; (setq col (- ncol (floor (/ num percol))))
; (cond ((equal col 1) (* 4 *nethoriz-spc*))
; ((equal col 2) *nethoriz-spc*)
; ((equal col 3) (* 2 *nethoriz-spc*))
; ((equal col 4) (* 3 *nethoriz-spc*)))
; )
)
)

(defun y-rel (num childcnt &optional (ycent (round (/ *netwin-y* 2))))
"Calculate y position of a given unit."
(if (equal *drawing-mode* 'circle)
(let (angle)
(setq angle (* num (/ (* 2 pi) childcnt)))
(round (+ ycent (* *y-radius* (sin angle))))
)
; (let (cc temp delt ncol percol) ; square format: do I need to keep this?
; (setq cc childcnt)
; (setq delt (round (/ (bitmap-height *grapher-grafport*)
; (if (< cc 16) (+ 2 cc) (+ 5 cc)))))
; (setq ncol 1) (setq percol cc)
; (if (< delt *netvert-spc*) (prog () (setq delt (* delt 2))
; (setq percol (round (/ percol 2.0)))
; (setq ncol (* ncol 2))))
; (if (< delt *netvert-spc*) (prog () (setq delt (round (* delt 2)))
; (setq percol (round (/ percol 2.0)))
; (setq ncol (* ncol 2))))
; (setq temp (- ncol (floor (/ num percol))))
; (round (* (+ (mod num percol)
; (if (and (oddp temp) (equal ncol 4)) 0.5 1)
; ) delt))
; )
)
)

(defun draw-around (unit)
"Basic function to draw the connections to a given unit."
(let (adj-lis xcent ycent childcnt
(winsize (view-size *netgraph-window*)))
(clear-bitmap *netgraph-window*)
(setq *unit-location-alist* nil)
(setq *netwin-x* (point-h winsize)) ; allows response to window resizing
(setq *netwin-y* (point-v winsize))
(setq *x-radius* (round (/ *netwin-x* 3.5)))
(setq *y-radius* (round (/ *netwin-y* 2.5)))
(setq xcent (round (/ *netwin-x* 2.0)))
(setq ycent (round (/ *netwin-y* 2.0)))
(setq adj-lis (linked-units unit))
(setq childcnt (length adj-lis))
(set-view-size *netgraph-window* winsize) ; allows response to window resizing
(do ((tlist adj-lis (cdr tlist))
(tunit nil nil)
(count 0 (1+ count))
(linkw nil nil)
)
((null tlist) nil)
(setq tunit (car tlist))
(setq linkw (weight-link-width unit tunit)) ; get a pattern dependent on weight
(set-pen-pattern *netgraph-window* linkw) ; set pen to the pattern
(draw-line *netgraph-window*
(make-position xcent ycent)
(make-position (x-rel count childcnt xcent)
(y-rel count childcnt ycent))
)
)
(set-pen-pattern *netgraph-window* *black-pattern*) ; restore pen to black pattern
(do ((tlist adj-lis (cdr tlist))
(tunit nil nil)
(count 0 (1+ count))
(xpt (x-rel 0 childcnt xcent)
(x-rel (1+ count) childcnt xcent)
)
(ypt (y-rel 0 childcnt ycent)
(y-rel (1+ count) childcnt ycent)
)
(word nil nil)
(str-pix-len nil nil)
)
((null tlist) nil)
(setq tunit (car tlist))
(draw-unit tunit xpt ypt)
(record-loc tunit xpt ypt)
(setq word (weight-link-label unit tunit))
(setq str-pix-len (with-pstrs ((str word))
(#_StringWidth :ptr str :word))
)
(draw-string *netgraph-window* ;stringblt *grapher-grafport*
(make-position
(round (/ (- (+ xpt xcent) str-pix-len) 2.0))
(+ (round (/ (+ ypt ycent) 2.0)) (round (/ *lbl-hgt* 2)))
)
; *grapher-font* ; can't set font at this point
word
)
)
(draw-unit unit xcent ycent)
; if you wanted to refresh-win the window, you'd do it here.
(refresh-win *netgraph-window*)
)
)

 

(defun record-loc (unit x y)
"Stores unit and rectangle containing it in the association-list."
(let ((top (- y *unit-radius*))
(bottom (+ y *unit-radius*))
(left (- x *unit-radius*))
(right (+ x *unit-radius*)))
(setq *unit-location-alist* (acons (list (list top bottom) left right) ; key
unit ; datum
*unit-location-alist* ; a-list
)
)
)
)

(defun search-loc (pt)
"Looks in a-list for the unit corresponding to this point."
(cdr (assoc pt *unit-location-alist* :test 'loc-test))
)

(defun loc-test (pt rect)
"Test for searching a-list for unit corresponding to pt."
(let ((x (point-h pt))
(y (point-v pt))
(vertrange (car rect))
(horizrange (cdr rect)))
(and (and (> y (car vertrange)) (< y (cadr vertrange)))
(and (> x (car horizrange)) (< x (cadr horizrange))))
)
)

(defun linked-units (unit)
"Default function to determine what is linked to a given unit (for ACME)."
(mapcar #'car (get unit 'links-from))
)

(defun weight-link-width (unit1 unit2)
"Function which determines the width of the line in various cases."
(let ((linkw (weight_of_link_between unit1 unit2)))
(cond ((< 0 linkw) *black-pattern*)
((> 0 linkw) *light-gray-pattern*)
((equal 0 linkw) *gray-pattern*)
((equal 0.0 linkw) *gray-pattern*)
)
)
)

(defun weight-link-label (unit1 unit2)
"Function which gives the label for the links (for ACME)."
(princ-to-string (/ (round (* (weight_of_link_between unit1 unit2) 1000))
1000.0
)
)
)

(defun actstring (unit)
"Default function to determine the second label for a unit (ACME)."
(princ-to-string (/ (round (* (act unit) 1000)) 1000.0))
)

 

(defun draw-unit (unit x y &optional (highlight nil))
"Basic unit drawing function."
(let (str-pix-len word)
(debug-print (list "drawing circle for" unit))
(draw-circle *netgraph-window* (make-position x y) *unit-radius* highlight)
(setq word (string unit))
(if (> (length word) *devowel-length*) (setq word (devowel word)))
(setq str-pix-len (with-pstrs ((str word))
(#_StringWidth :ptr str :word)))

(draw-string *netgraph-window*
(make-position
(- x (round (/ str-pix-len 2.0)))
(- y (+ *unit-radius* 5))) ; this 5 may be a function of *lbl-hgt* ?
;*grapher-font*
word
)
(setq word (actstring unit))
(setq str-pix-len (with-pstrs ((str word))
(#_StringWidth :ptr str :word)))
(draw-string *netgraph-window*
(make-position
(- x (round (/ str-pix-len 2.0)))
(+ y (+ *unit-radius* 15))) ; this 15 may be a function of *lbl-hgt* ?
;*grapher-font*
word
)
(debug-print (list "done drawing" unit))
)
)

 

 

 

;;;;;;;;;; Activation grapher (ag)

 

 

 

(defun reset-act (&optional unit-list no-sort)
"Prepare the grapher to trace the activations of units in unit-list."
(let ((winsize (view-size *actgraph-window*)))
(setq *actwin-x* (point-h winsize)) ; recalculate window dimensions and graph
(setq *actwin-y* (point-v winsize)) ; distribution, in case window has been
(setq *graphs-per-line* (truncate *actwin-x* *graph-wid*)) ; resized
)
(prog (x y word (glines (/ *actwin-y* *graph-hgt*)))
(cond ((and (null unit-list) (null *unit-list*))
(print "No previously defined unit-list exists.")
(return nil))
((null unit-list) (setq unit-list *unit-list*))
)
(cond ((> (length unit-list) (* glines *graphs-per-line*)) ; more units to graph than will fit?
(format t "~%Too many units to graph. Max is ~d units.~%"
(round (* glines *graphs-per-line*)))
(cond
((equal *run-type* 'slow)
(let ((size (view-size *actgraph-window*)))
(format t "Enter list of units to graph, or resize window and enter (): ")
(cond ((and (null (setq unit-list (read))) ; If no list entered, and window not
(equal size (view-size *actgraph-window*))) ; resized, terminate graphing.
(format t "~%Not graphing any units.~%")
(window-close *actgraph-window*) ; close window
; (setq *use-actgraph* nil) ; turn off grapher: this is a hassle
(return nil) ; but otherwise show-act is called
) ; and you get an error
((and (> (point-h (view-size *actgraph-window*)) (point-h size))
(not (< (point-v (view-size *actgraph-window*)) (point-v size))))
(reset-act )
(return-from reset-act nil)
)
)
)
)
(t (format t "Terminating graphing.~%")
(window-close *actgraph-window*)
; (setq *use_actgraph* nil) ; turn off grapher: hassle as above
(return nil) ; Could have run_hyp_net check if
) ; window is open, but this is neater.
)
)
)

;; these two lines have been commented out because sort won't behave
;; (basically it only returns the first item in the list)
;; (if (null no-sort)
;; (stable-sort unit-list #'string-lessp :key #'symbol-name))

(setq *act-list* (rep default_activation (length unit-list)))
(setq *unit-list* unit-list)
(setq *time-step* 0)
; allows response to window resizing
(set-view-size *actgraph-window* (view-size *actgraph-window*))
(clear-bitmap *actgraph-window*)
(do ((ul (cdr *unit-list*) (cdr ul))
(un (car *unit-list*) (car ul))
(pos 0 (1+ pos)))
((null un) nil)
(setf (get un 'activation) default_activation)
(setq x (+ (round (* (mod pos *graphs-per-line*)
*graph-wid*)) *left-margin*))
(setq y (+ (round (* (+ (truncate (/ pos *graphs-per-line*)) 1) *graph-hgt*))
*top-margin*))
(setq word (string un))
(if (> (length word) *devowel-length*) (setq word (devowel word)))
(draw-string *actgraph-window*
(make-position x ;(+ y *graph-hgt*) ;this puts labels *vert-spc* pixels above axes
y) ; while this puts labes 0 pixels below axes
;*grapher-font* ; maybe can implement this later
word
)
(draw-line *actgraph-window* ;; DRAW AXES
(make-position x (- y (+ *axis-hgt* *lbl-hgt*)))
(make-position x (- y *lbl-hgt*))
)
(draw-line *actgraph-window*
(make-position x (- y (+ (/ *axis-hgt* 2) *lbl-hgt*)))
(make-position (+ x ;(round (/ (- *actwin-x* (* *horiz-spc*
; *graphs-per-line*))
; *graphs-per-line*))
*axis-wid*
)
(- y (+ (/ *axis-hgt* 2) *lbl-hgt*)))
)
)
(refresh-win *actgraph-window*) ; redraw everything in window so Labels are in
; same font as in bitmap. (Hack.)
)
)

 

(defun show-act ()
"The real function to show the activation of the current *unit-list*."
(if (wptr *actgraph-window*)
(let (nal)
(do ((ul (cdr *unit-list*) (cdr ul))
(al (cdr *act-list*) (cdr al))
(un (car *unit-list*) (car ul))
(ac (car *act-list*) (car al))
(pos 0 (1+ pos)))
((null un) nil)
(draw-delta-line pos
(* (act un) (- 0 (/ *axis-hgt* 2)))
(* ac (- 0 (/ *axis-hgt* 2))))
(setq nal (append nal (list (act un))))
)
(setq *act-list* nal)
(setq *time-step* (1+ *time-step*))
)
)
)

(defun draw-delta-line (pos new-a old-a)
"Function to redraw the individual units with a new activation."
(let (x y (xs (/ *axis-wid* (car (last *when-to-print*)))))
(setq x (+ (round (* (mod pos *graphs-per-line*)
*graph-wid*))
(* *time-step* xs) *left-margin*))
(setq y (+ (+ (* (truncate pos *graphs-per-line*) *graph-hgt*) (/ *axis-hgt* 2))
*top-margin* *vert-spc*
)
)
(draw-line *actgraph-window*
(make-position (1+ (round (- x xs))) (round (+ y old-a)))
(make-position (round x) (round (+ y new-a)))
)
)
)

 

(defun act (unit)
"Function to determine the activation of a unit."
(get unit 'activation)
)

(defun debug-print (message)
(if (null *debug*) nil (print message)))