;;;; -*- mode:Lisp; syntax:Common-Lisp; package:user -*- ;;;; ;;;; Copyright 1992 Patrick H. Winston. All rights reserved. ;;;; Version 1.1, copied from master file on 21 Jan 93 ;;;; ;;;; This software is licensed by Patrick H. Winston (licensor) for ;;;; instructional use with the textbooks ``Artificial Intelligence,'' by ;;;; Patrick H. Winston, and ``Lisp,'' by Patrick H. Winston and Berthold ;;;; K. P. Horn. Your are free to make copies of this software and ;;;; modify it for such instructional use as long as: ;;;; 1. You keep this notice intact. ;;;; 2. You cause any modified files to carry a prominent notice stating ;;;; that you modified the files and the date of your modifications. ;;;; This software is licensed ``AS IS'' without warranty and the licensor ;;;; shall have no liability for any alleged defect or damages. ;;;; REMARKS #| This version uses delayed evaluation. Note that ENCAPSULATE is designed so that each stream element is computed only once. |# ;;;; BASIC ACCESS FUNCTIONS WITH DELAYED EVALUATION (defun make-empty-stream () 'empty-stream) (defun stream-endp (stream) (eq stream 'empty-stream)) (defun stream-first (stream) (first stream)) (defun stream-rest (stream) (expose (second stream))) (defmacro stream-cons (object stream) `(list ,object (encapsulate ,stream))) (defun stream-append (stream1 stream2) (if (stream-endp stream1) stream2 (stream-cons (stream-first stream1) (stream-append (stream-rest stream1) stream2)))) (defun stream-concatenate (streams) (if (stream-endp streams) 'empty-stream (if (stream-endp (stream-first streams)) (stream-concatenate (stream-rest streams)) (stream-cons (stream-first (stream-first streams)) (stream-concatenate (stream-cons (stream-rest (stream-first streams)) (stream-rest streams))))))) (defun stream-transform (procedure stream) (if (stream-endp stream) 'empty-stream (stream-cons (funcall procedure (stream-first stream)) (stream-transform procedure (stream-rest stream))))) (defun stream-member (object stream) (cond ((stream-endp stream) nil) ((equal object (stream-first stream)) t) (t (stream-member object (stream-rest stream))))) (defmacro stream-remember (object variable) `(unless (stream-member ,object ,variable) (setf ,variable (stream-append ,variable (stream-cons ,object 'empty-stream))) ,object)) ;;;; AUXILIARY PROCEDURES FOR LEXICAL ENCAPSULATION (defmacro encapsulate (form) ;From a problem solution. `(let ((switch nil) (result nil)) #'(lambda () (if switch result (setf switch t result ,form))))) (defmacro expose (procedure) `(funcall ,procedure))