Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[88]

(define (adder a1 a2 sum) (define (process-new-value)

(cond ((and (has-value? al) (has-value? a2)) (set-value! sum

(+ (get-value a1) (get-value a2))

me))

((and (has-value? al) (has-value? sum)) (set-value! a2

(- (get-value sum) (get-value a1))

me))

((and (has-value? a2) (has-value? sum)) (set-value! a1

(- (get-value sum) (get-value a2))

me))))

(define (process-forget-value) (forget-value! sum me) (forget-value! a1 me) (forget-value! a2 me) (process-new-value)) (define (me request)

(cond ((eq? request I-have-a-value) (process-new-value)) ((eq? request I-lost-my-value)

(process-forget-value)) (else

(error "Неизвестный запрос -- ADDER" request)))) (connect a1 me) (connect a2 me) (connect sum me) me)

Adder связывает новый сумматор с указанными соединителями и возвращает его в качестве значения. Процедура me, которая представляет сумматор, работает как диспетчер для внутренних процедур. Для доступа к диспетчеру используются следующие «синтаксические интерфейсы» (см. примечание 27 в разделе 3.3.4):

(define (inform-about-value constraint) (constraint I-have-a-value))

(define (inform-about-no-value constraint) (constraint I-lost-my-value))

Внутренняя процедура сумматора process-new-value вызывается, когда сумматору сообщают, что один из его соединителей получил значение. Сумматор проверяет, имеют ли значения одновременно a1 и a2. Если да, то он говорит sum, чтобы тот установил значение в сумму двух слагаемых. Аргумент informant процедуры set-value! равен me, то есть самому объекту-сумматору. Если неверно, что и a1 и a2 имеют значения, то сумматор проверяет, имеют ли одновременно значения a1 и sum. Если да, то он устанавливает a2 в их разность. Наконец, если значения есть у a2 и sum, это дает сумматору достаточно информации, чтобы установить a1. Если сумматору сообщают, что один из соединителей потерял значение, то он просит все свои


соединители избавиться от значений. (На самом деле будут отброшены только значения, установленные самим сумматором.) Затем он зовет process-new-value. Смысл этого последнего шага в том, что один или более соединителей по-прежнему могут обладать значением (то есть, у соединителя могло быть значение, не установленное сумматором), и эти значения может быть необходимо распространить через сумматор.

Умножитель очень похож на сумматор. Он устанавливает свой вывод product в 0, если хотя бы один множитель равен 0, даже в том случае, когда второй множитель неизвестен.

(define (multiplier m1 m2 product) (define (process-new-value)

(cond ((or (and (has-value? ml) (= (get-value ml) 0)) (and (has-value? m2) (= (get-value m2) 0))) (set-value! product 0 me)) ((and (has-value? m1) (has-value? m2)) (set-value! product

(* (get-value ml) (get-value m2))

me))

((and (has-value? product) (has-value? ml)) (set-value! m2

(/ (get-value product) (get-value ml))

me))

((and (has-value? product) (has-value? m2)) (set-value! ml

(/ (get-value product) (get-value m2))

me))))

(define (process-forget-value) (forget-value! product me) (forget-value! ml me) (forget-value! m2 me) (process-new-value)) (define (me request)

(cond ((eq? request I-have-a-value) (process-new-value)) ((eq? request I-lost-my-value)

(process-forget-value)) (else

(error "Неизвестный запрос -- MULTIPLIER" request)))) (connect ml me) (connect m2 me) (connect product me) me)

Конструктор constant просто устанавливает значение указанного соединителя. Сообщение I-have-a-value либо I-lost-my-value, посланные блоку-константе, приводят к ошибке.

(define (constant value connector) (define (me request)

(error "Неизвестный запрос -- CONSTANT" request)) (connect connector me) (set-value! connector value me) me)


Наконец, тестер печатает сообщение о присваивании или потере значения в указанном соединителе:

(define (probe name connector) (define (print-probe value) (newline)

(display "Тестер: ") (display name) (display " = ") (display value)) (define (process-new-value)

(print-probe (get-value connector))) (define (process-forget-value)

(print-probe "?")) (define (me request)

(cond ((eq? request I-have-a-value) (process-new-value)) ((eq? request I-lost-my-value)

(process-forget-value)) (else

(error "Неизвестный запрос -- PROBE" request)))) (connect connector me) me)

Представление соединителей

Соединитель представляется в виде процедурного объекта с внутренними переменными состояния: value, значение соединителя; informant, объект, который установил значение соединителя; и constraints, множество ограничений, в которых участвует соединитель.

(define (make-connector)

(let ((value false) (informant false) (constraints ())) (define (set-my-value newval setter) (cond ((not (has-value? me)) (set! value newval) (set! informant setter) (for-each-except setter

inform-about-value constraints)) ((not (= value newval))

(error "Противоречие" (list value newval))) (else ignored))) (define (forget-my-value retractor) (if (eq? retractor informant)

(begin (set! informant false)

(for-each-except retractor

inform-about-no-value constraints))

ignored)) (define (connect new-constraint)

(if (not (memq new-constraint constraints)) (set! constraints

(cons new-constraint constraints)))



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]