|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[85] (else (error "Неизвестная операция -- WIRE" m)))) dispatch)) Внутренняя процедура set-my-signal! проверяет, отличается ли новое значение сигнала в проводе от старого. Если да, то она запускает все процедуры-действия при помощи процедуры call-each, которая по очереди вызывает элементы списка безаргументных процедур: (define (call-each procedures) (if (null? procedures) done (begin ((car procedures)) (call-each (cdr procedures))))) Внутренняя процедура accept-action-procedure! добавляет процедуру-аргумент к списку действий, а затем один раз запускает новую процедуру. (См. упражнение 3.31.) Располагая вышеописанной процедурой dispatch, мы можем написать сле- 27 дующие процедуры для доступа к внутренним операциям над проводами:27 (define (get-signal wire) (wire get-signal)) (define (set-signal! wire new-value) ((wire set-signal!) new-value)) (define (add-action! wire action-procedure) ((wire add-action!) action-procedure)) Провода, которые содержат меняющиеся со временем сигналы и могут подсоединяться к одному объекту за другим, - типичный образец изменяющихся объектов. Мы смоделировали их в виде процедур с внутренними переменными состояния, которые изменяются присваиванием. При создании нового провода создается новый набор переменных состояния (в выражении let внутри make-wire), а также порождается и возвращается новая процедура dispatch, которая захватывает окружение с новыми переменными состояния. Провода разделяются между различными устройствами, к ним подсоединенными. Таким образом, изменение, произведенное при взаимодействии с одним устройством, скажется на всех других устройствах, связанных с этим проводом. Провод передает изменение своим соседям, вызывая процедуры-действия, зарегистрированные в нем в момент установления соединения. 27Эти процедуры - всего лишь синтаксический сахар, который позволяет нам работать с внутренними процедурами объектов, используя обычный синтаксис процедурного вызова. Поразительно, что мы так просто можем менять местами роли процедур и данных. Например, когда мы пишем (wire get-signal), мы представляем себе провод wire как процедуру, вызываемую с сообщением get-signal на входе. С другой стороны, запись (get-signal wire) поощряет нас думать о wire как об объекте данных, который поступает на вход процедуре get-signal. Истина состоит в том, что в языке, где с процедурами можно работать как с объектами, никакого фундаментального различия между «процедурами» и «данными» не существует, и мы имеем право выбирать такой синтаксический сахар, который позволит программировать в удобном для нас стиле. План действий Теперь для завершения модели нам остается только написать after-delay. Здесь идея состоит в том, чтобы организовать структуру данных под названием план действий (agenda), где будет храниться расписание того, что нам надо сделать. Для планов действий определены следующие операции: •(make-agenda) возвращает новый пустой план действий. •(empty-agenda? (план-действий)) истинно, если план пуст. •(first-agenda-item (план-действий)) возвращает первый элемент плана. •(remove-first-agenda-item! (план-действий)) модифицирует план, убирая из него первый элемент. •(add-to-agenda! (время) (действие) (план-действий)) модифицирует план, добавляя указанную процедуру-действие, которую нужно запустить в указанное время. •(current-time (план-действий)) возвращает текущее время модели. Экземпляр плана, которым мы будем пользоваться, будет обозначаться the-agenda. Процедура after-delay добавляет новый элемент в план the-agenda: (define (after-delay delay action) (add-to-agenda! (+ delay (current-time the-agenda)) action the-agenda)) Имитация управляется процедурой propagate, которая работает с the-agenda, по очереди выполняяпроцедуры, содержащиеся в плане. В общем случае, при работе модели в план добавляются новые элементы, а propagate продолжает работу, пока план не становится пустым: (define (propagate) (if (empty-agenda? the-agenda) done (let ((first-item (first-agenda-item the-agenda))) (first-item) (remove-first-agenda-item! the-agenda) (propagate)))) Пример работы модели Следующая процедура, которая навешивает на провод «тестер», показывает имитационную модель в действии. Тестер говорит проводу, что, каждый раз, когда сигнал изменяет значение, нужно напечатать новое значение сигнала, а также текущее время и имя провода: (define (probe name wire) (add-action! wire (lambda () (newline) (display name) (display " ") (display (current-time the-agenda)) (display " New-value = ") (display (get-signal wire))))) Сначала мы инициализируем план действий и указываем задержки для элементарных функциональных элементов: (define the-agenda (make-agenda)) (define inverter-delay 2) (define and-gate-delay 3) (define or-gate-delay 5) Затем мы создаем четыре провода и к двум из них подсоединяем тестеры: (define input-1 (make-wire)) (define input-2 (make-wire)) (define sum (make-wire)) (define carry (make-wire)) (probe sum sum) sum 0 New-value = 0 (probe carry carry) carry 0 New-value = 0 Затем мы связываем провода, образуя схему полусумматора (как на рис. 3.25), устанавливаем сигнал на входе input-1 в 1, и запускаем модель: (half-adder input-1 input-2 sum carry) ok (set-signal! input-1 1) done (propagate) sum 8 New-value = 1 done Сигнал sum становится 1 в момент времени 8. Мы находимся в 8 единицах от начала работы модели. В этот момент мы можем установить сигнал на входе input-2 в 1 и дать изменению распространиться: (set-signal! input-2 1) done (propagate) carry 11 New-value = 1 sum 16 New-value = 0 done Сигнал carry становится равным 1 в момент 11, а sum становится 0 в момент 16. |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||