;;; -*- mode: LISP; Package: CL-USER; Syntax: COMMON-LISP; Base: 10 -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Author : Mike Byrne ;;; Copyright : (c)2006 Rice U./Mike Byrne, All Rights Reserved ;;; Availability: Covered by the GNU LGPL, see LGPL.txt ;;; Address : Rice University ;;; : Psychology Department ;;; : Houston,TX 77251-1892 ;;; : byrne@acm.org ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Filename : agm-time.lisp ;;; Version : b3 ;;; ;;; Description : Alternate temporal module for ACT-R. This one is based on ;;; : the attentional gate model [AGM] of Block and Zakay. ;;; ;;; Bugs : ;;; ;;; Todo : ;;; ;;; ----- History ----- ;;; 2006.07.20 mdb [b3] ;;; : Took out some old debugging code. Oops. ;;; 2006.07.07 mdb [b2] ;;; : Addressed possible problem with negative pulse duration. ;;; 2006.06.26 mdb ;;; : b1 release. ;;; 2006.06.16 mdb ;;; : Incept date. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #| Start the pacemaker with this: +temporal> isa start Inquire about the presence of a new pulse via LHS: ?temporal> new-pulse yes Increment the counter via RHS (need to have matched =temporal> on LHS) +temporal> count increment Read off the counter with LHS: =temporal> isa counter count =c Reset the counter with RHS (but this will keep pacemaker active): +temporal> isa clear Stop the pacemaker with RHS: +temporal> isa stop And that's all we support for now. |# #+:packaged-actr (in-package :act-r) #+(and :clean-actr (not :packaged-actr) :ALLEGRO-IDE) (in-package :cg-user) #-(or (not :clean-actr) :packaged-actr :ALLEGRO-IDE) (in-package :cl-user) (defclass time-module () ((pulse-rate :accessor pulse-rate :initarg :pulse-rate :initform 0.250) (pulse-noise :accessor pulse-noise :initarg :pulse-noise :initform 0) (new-pulse? :accessor new-pulse? :initarg :new-pulse? :initform nil) (next-pulse :accessor next-pulse :initarg :next-pulse :initform (mp-time)) (counter :accessor counter :initarg :counter :initform 0) (is-timing? :accessor is-timing? :initarg :is-timing? :initform nil) ) ) (defmethod pulse ((tmod time-module)) (when (is-timing? tmod) (setf (new-pulse? tmod) t) (let ((pulse-width (+ (pulse-rate tmod) (act-r-noise (pulse-noise tmod))))) ;; make pulses be minimum of 5 ms apart. Should this be a parameter? (if (> pulse-width 0) (incf (next-pulse tmod) pulse-width) (incf (next-pulse tmod) 0.005))) (schedule-event (next-pulse tmod) 'pulse :destination :temporal :module 'temporal :priority 20) (next-pulse tmod))) (defun query-time-module (instance buffer-name slot value) (declare (ignore buffer-name)) (case slot (state (case value (busy (is-timing? instance)) (free (not (is-timing? instance))) (error nil) (t (print-warning "Unknown state query ~S to time module" value) nil))) (new-pulse (case value (yes (new-pulse? instance)) (no (not (new-pulse? instance))) (t (print-warning "Unknown NEW-PULSE query ~S to time module" value) nil))) (t (print-warning "Unknown query of the temporal module"))) ) (defun time-module-request (tmod buffer-name chunk-spec) (declare (ignore buffer-name)) (case (chunk-spec-chunk-type chunk-spec) ;; start the counter (start (schedule-event-relative 0 'create-new-buffer-chunk :module 'temporal :priority -100 :details "create-new-buffer-chunk isa counter" :params (list 'temporal '(isa counter count 0))) (setf (is-timing? tmod) t) (setf (counter tmod) 0) (setf (next-pulse tmod) (mp-time)) (pulse tmod) (setf (new-pulse? tmod) nil) ) ;; reset the counter (clear (setf (counter tmod) 0) (setf (next-pulse tmod) (+ (next-pulse tmod) (pulse-rate tmod) (act-r-noise (pulse-noise tmod)))) (schedule-event (next-pulse tmod) 'pulse :destination :temporal :module 'temporal :priority 20)) (stop (setf (is-timing? tmod) nil)) (t (print-warning "Invalid command ~a sent to the temporal buffer" (chunk-spec-chunk-type chunk-spec))) )) (defun params-time-module (tmod param) (if (consp param) (case (car param) (:pulse-rate (setf (pulse-rate tmod) (rest param))) (:pulse-noise (setf (pulse-noise tmod) (rest param)))) (case param (:pulse-rate (pulse-rate tmod)) (:pulse-noise (pulse-noise tmod))))) (defun reset-time-module (instance) (sgp :do-not-harvest temporal) (chunk-type counter count) (chunk-type start) (chunk-type stop) (setf (is-timing? instance) nil) ) (defun mod-time-buffer (instance buffer mod-request) (declare (ignore buffer)) (if (not (equal mod-request '(count increment))) (print-warning "Invalid buffer mod ~S sent to temporal buffer" mod-request) (progn (incf (counter instance)) (schedule-mod-buffer-chunk 'temporal (list 'count (counter instance)) 0 :module 'temporal :priority 10) (setf (new-pulse? instance) nil) ))) (define-module-fct :temporal (list (list 'temporal nil nil '(new-pulse))) (list (define-parameter :pulse-rate :valid-test #'posnum :default-value 0.250 :warning "a non-negative number" :documentation "Beat rate for the pacemaker") (define-parameter :pulse-noise :valid-test #'posnum :default-value 0 :warning "a non-negative number" :documentation "Noise in the beat rate for the pacemaker") ) :version "1.0b1" :documentation "Temporal module based on Block & Zakay's AGM" :creation #'(lambda (x) (declare (ignore x)) (make-instance 'time-module)) :reset (list nil 'reset-time-module) :query 'query-time-module :request 'time-module-request :params 'params-time-module :buffer-mod 'mod-time-buffer ) #| This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |#