Главная страница
Навигация по странице:

  • (printout t "Continue ") (bind answer (read)) (while (and (neq

  • (case divided-by then (printout t arg1 " divided by " arg2 is " (/

  • (* argl arg2) crlf)) (defrule perform-operation-plus (operation plus

  • дб. Четвертое издание джозеф Джарратано Университет Хьюстон клиэрЛэйк Гари Райли People5oft, Издательский дом "Вильямс" Москва СанктПетербург Киев 2007 ббк 32. 973. 26 018 75 Д


    Скачать 3.73 Mb.
    НазваниеЧетвертое издание джозеф Джарратано Университет Хьюстон клиэрЛэйк Гари Райли People5oft, Издательский дом "Вильямс" Москва СанктПетербург Киев 2007 ббк 32. 973. 26 018 75 Д
    Дата19.05.2022
    Размер3.73 Mb.
    Формат файлаpdf
    Имя файла[Dzharratano Dzhozef, Raili Gar - Nieizviestnyi.pdf
    ТипДокументы
    #538649
    страница60 из 74
    1   ...   56   57   58   59   60   61   62   63   ...   74

    (and (or (у у) (y '.y2) (y уз) (eq ?хЗ (eq ?хЗ (eq ?z2 (z ?z1)) (z ?
    z2)) (z ?гЗ)) green) red)) ?уЗ) (> ух г Х) (лесу ?гЗ х) =>) 9.24. На рис. 9.15 показана сеть диагностирования неисправностей для гипотетических компонентов оборудования.
    Стрелки указывают направление, в котором распространяются неисправности. Например, при возникновении неисправности в компоненте А неисправности возникают ив компонентах В и С 778 Глава 9. Модульное проектирование, управление выполнением. Рис. 9.15. Сеть диагностирования неисправностей гипотетических компонентов оборудования Ниже приведены правила, которые описывают распространение неисправностей посети В) (assert (fault С) (defrule С (fault С) (assert (fault device-D))
    (assert (fault device-E))) (defrule propagate-device-E-fault (fault device-E) (assert (fault device-F))) Перепишите эти три правила в виде одного общего правила и конструкции de f f acts, которые
    будут описывать распространение неисправностей также, как и три приведенных выше правила. Объясните, какие изменения потребуется внести при использовании каждого из этих двух вариантов организации программы после добавления нового компонента к сети диагностирования неисправностей ,.... 10 Процедурное программирование 10.1 Введение В
    языке CLIPS предусмотрены средства процедурного программирования, аналогичные тем, которые применяются в таких языках, как Си. В настоящей главе приведено вводное описание этих средств. Иногда бывает более удобно (и более эффективно) осуществлять некоторые операции с использованием подхода, базирующегося на процедурном программировании, а не подхода, основанного на правилах. В
    настоящей главе вначале рассматривается ряд процедурных функций, включая определенные функции, которые обеспечивают организацию циклов и выбор путей передачи управления по условию. Для определения новых функций,
    которые могут вызываться из правил или других функций,
    предназначена конструкция de f f unction. Конструкция de f global позволяет определять глобальные переменные. В отличие от локальных переменных, определяемых в правилах или функциях, глобальные переменные всегда сохраняют свои значения. Конструкции de f gener i c и de f method обеспечивают создание универсальных функций, которые подобны обычным функциям, за исключением того, что выполняемый в них код зависит от количества и типов параметров, передаваемых в функцию. Наконец, в данной главе дано вводное описание целого ряда полезных вспомогательных функций. Процедурные функции В языке CLIPS предусмотрено несколько функций, предназначенных для управления потоком выполнения действий. Функции while, if, switch, loop forcount, progn$ и break предоставляют функциональные возможности, аналогичные управляющим структурам, которые предусмотрены в таких современных язы-

    780 Глава 10. Процедурное программирование Функция дй
    Функция i f имеет следующий синтаксис (if expression> then + [else +]) В этом определении
    — это единственное выражение (такое как предикативная функция или переменная),
    а параметр +, который следует за ключевыми словами if и then, представляет собой одно или несколько выражений, которые должны быть вычислены с учетом значения, полученного в результате вычисления выражения. Обратите внимание на то, что выражение else является необязательным. При выполнении функции if вначале проверяется условие, представленное выражением
    , для определения того,
    должны ли быть выполнены действия, заданные в конструкции then или else. Если проверка условия приводит к получению любого символа, отличного от FALSE, то выполняются действия,
    заданные в конструкции then этой функции, а если проверка условия приводит к получению символа FALSE, то выполняются действия, заданные в конструкции else. Если же конструкция else не включена, то после получения ложных результатов проверки условия никакие действия не выполняются. Сразу после завершения выполнения функции i f система переходит к выполнению следующего действия в правой части правила, если оно имеется. Функцию if удобно использовать для проверки значений в правой части правила, поскольку это позволяет избавиться от необходимости осуществлять проверку с помощью других правил. Например, с помощью следующего правила можно определить, должно ли быть продолжено выполнение программы ках высокого уровня, как Ada, Pascal и
    С. Кроме того, функция halt, заданная в правой части любого правила, позволяет остановить выполнение правил. Язык в первую очередь предназначен для использования в качестве эффективного языка, основанного на правилах, а процедурные функции, рассматриваемые в этой главе, предусмотрены лишь для ограниченного применения. Попытка написать объемистую
    процедурную программу, включив ее в правую часть правила,
    противоречит общему назначению языка, основанного на правилах. Поэтому, вообще говоря, такие функции должны использоваться для выполнения простых проверок и циклов в правой части правила, и следует избегать применения в правых частях правил сложных вложенных конструкций, состоящих из процедурных функций 10.2. Процедурные функции (defrule continue-check ?phase <-
    (phase check-continue) — > (retract ?phase) (printout t "Continue? ")
    (bind ?answer (read)) (if (or (eq ?answer у) (eq ?answer yes)) then
    (assert (phase continue)) else (assert (phase halt)))) Следует отметить, что функция if позволяет преобразовать положительный или отрицательный ответили по, в факт,
    указывающий, какого типа действие должно быть предпринято.
    В рассматриваемом случае таким действием становится либо continue, либо halt. Возвращаемым значением функции i f является результат вычисления последнего выражения в части then или else функции. Если результатом вычисления выражения становится FALSE ив функции отсутствует часть then, то функция возвращает символ. Функция while Функция while имеет следующий синтаксис (while
    [do] *) В
    этом определении представляет собой единственное выражение (такое как предикативная функция или переменная, а параметр *, который следует за необязательным ключевым словом do, обозначает от нуля или больше выражений, которые должны быть вычислены с учетом значения, возвращаемого в результате вычисления выражения. Эти выражения составляют тело цикла.
    Та часть функции while, которая представлена выражением, вычисляется до выполнения действий,
    предусмотренных в теле цикла. Если вычисление выражения приводит к получению любого значения, отличного от символа FALSE, то выполняются
    выражения, представленные в теле цикла. Если же вычисление выражения приводит к получению символа FALSE, то программа переходит к выполнению оператора, который следует за функцией while, если таковой имеется. Условие функции while проверяется каждый раз перед выполнением операторов в теле цикла для определения того,
    должны ли они быть снова выполнены.
    Глава 10. Процедурное программирование 782 (defrule continue- check ?phase <- (phase check-continue) — > (retract ?phase)

    (printout t "Continue? ") (bind ?answer (read)) (while (and (neq ?
    answer yes) (neq ?answer по) do (printout t "Continue? ") (bind ?
    answer (read))) (if (eq ?answer yes) then (assert (phase continue))
    else (assert (phase halt)))) Функция switch Функция switch имеет следующий синтаксис (switch * []) В этом определении оператор se — statement> имеет следующую форму (case
    then *) а оператор определен таким образом (default
    *) Часть *, которая следует за ключевыми словами then и de— йаы1

    , состоит из одного или нескольких выражений, которые должны быть вычислены с учетом возвращаемого значения выражения expression>, сравниваемого с возвращаемым значением выражения Следует учитывать, что необязательный вариант сазе, обозначаемый как default, должен быть расположен после всех других конструкций сазе. После передачи управления функции switch вначале вычисляется часть, представленная выражением . После этого вычисляется каждое из выражений expression> в том порядке, в котором они заданы в определении функции, и если результат сов- Функция while может использоваться вместе с функцией if для проверки ошибок ввода в правой части правила. Ниже приведена еще одна модификация правила continue — check, в которой
    применяется функция while для определения условия продолжения цикла до тех пор, пока не будет получен приемлемый ответ. Процедурные функции 783 падает с результатом вычисления выражения , то выполняются действия, заданные после ключевого слова then, и работа функции switch завершается. Если не найдено ни одно выражение , значение которого совпадало бы со значением , и задан вариант , то выполняются действия,
    определяемые вариантом . В
    приведенном ниже коде функция switch используется для установления соответствия между символическими именами и знаками арифметических функций. (defrule perform-operation
    (operation ?type ?arg1 ?arg2) > (switch ?type (case times then
    (printout t ?arg1 " times " ?arg2 is " (* ?arg1 ?arg2) crlf)) (case plus then (printout t ?arg1 " plus " ?arg2 is " (+ ?arg1 ?arg2) crlf)) (case minus then (printout t ?argl " minus " ?arg2 is " (- ?arg1 ?arg2) crlf))

    (case divided-by then (printout t ?arg1 " divided by " ?arg2 is " (/ ?
    arg1 ?arg2) crlf)))) В качестве примера можно привести следующий диалог CLIPS> (assert (operation plus 3 4))J
    CLIPS> (ги) 3 plus 4 is 7 CLIPS> Символ plus в факте operation вызывает переход к варианту саяе со значением plus в операторе switch, после чего выводится результат сложения чисел 3 и Глава 10. Процедурное программирование 784 Приведенное выше правило perform — operation можно записать иначе, в виде четырех отдельных правил, те. без использования функции switch, следующим образом (defrule perform-operation-times
    (operation times ?argl ?arg2) => (printout t ?argl " times " ?arg2 is "

    (* ?argl ?arg2) crlf)) (defrule perform-operation-plus (operation plus ?
    argl ?arg2) — > (printout t ?argl " plus " ?arg2 is " (+ ?argl ?arg2)
    crlf)) (defrule perform-operation-minus (operation minus ?argl ?arg2)
    — > (printout t ?argl " minus " ?arg2 is " (- ?argl ?arg2) crlf)) (defrule perform-operation-divided-by (operation divided-by ?argl ?arg2) =>
    (printout t ? argl " divided by " ? arg2 is " (/ ?argl ?arg2) Функция loop- for-count Функция loop — for — count имеет следующий синтаксис (loop-for-count [do]
    *) В этом определении конструкция имеет такую форму ( )
    ( ) В данном случае — index> и представляют собой выражения,
    которые возвращают целые числа. Если задано только выражение , то оно рассматривается как количество итераций выполнения тела функции, определяемого параметром *. Если заданы выражения variable> и , то осуществляется указанное количество итераций выполнения тела функции, а текущий номер итерации, возрастающий в пределах от 1 до index>, сохраняется в переменной на каждой итерации. Если кроме этого задано выражение. Процедурные функции 785 , то отсчет количества итераций начинается со значения , а неси количество выполняемых итераций определяется как разность между значениями и больше чем index>, то никакие итерации не выполняются. Ниже приведен пример, в котором используются все три составляющие конструкции и вложенные вызовы функции loop- for-count. CLIPS> (loop-for-count (?cnt1 2 4) do (loop-for-count (?
    cnt2 3) do (printout t ?cnt1 " ") (loop-for-count 3 do (printout t "."))
    (printout t " " ?cnt2 crlf)))J 2 ... 1 2 ... 2 2 . ° ° 3 3 ... 1 3 ... 2 3 ... 3 4 ..
    ° 1 4 ... 2 4 ... 3 FALSE CLIPS> Переменная (defrule masking-example (bind х 4) (loop-
    for-count (х 2) do (printout t "inside ?x is " ?x crlf)) (printout t
    "outside ?x is " ?x crlf))J CLIPS> (reset)J CLIPS> (й1иЪ) inside х is
    1 inside х is 2 outside х Глава 10. Процедурное программирование is 4 Функция progn$ Функция progn$ имеет следующий синтаксис *) В этом определении параметр — spec> задается в такой форме
    ( ) CLIPS> (progn$ (create$ 1 2 3) (printout t . crlf)) ! CLIPS> (рходп$ (7v (create$ а b с))
    (рхiп1оиi. t ?v-index " " 7v crlf))J 1 а 2 Ь 3 с CLIPS> Если задан не только параметр , но и параметр , то тело функции, представленное как, выполняется по одному разу для каждого поля в результирующем многозначном значении, которое получено в результате вычисления выражения Применение параметра вместе с параметром позволяет осуществлять выборку поля текущей итерации, ссылаясь на переменную. Кроме того,
    создается специальная переменная путем добавления суффикса -index к имени параметра . Эта переменная содержит индекс текущей итерации. Возвращаемым значением данной функции является возвращаемое значение последнего выражения , вычисленного для последнего поля параметра . Вызовы функции loop — for — count, как и вызовы функции progn$, могут вкладываться, а переменные, созданные для выражения маскируют переменные, объявленные вне выражения имеющие тоже имя. Ниже приведены примеры использования обоих вариантов представления параметра .
    10.2. Процедурные функции 787 Функция break Функция break имеет следующий синтаксис (break) Функция break прекращает выполнение той функции while, loop-forcount или progn$, в
    которой она непосредственно обнаруживается. Обычно функция break используется, чтобы вызвать преждевременное завершение цикла при обнаружении некоторого условия.
    Например, правило print-list, показанное в приведенном ниже диалоге, выводит первые пять элементов из списка, а затем выводит многоточие, если есть еще оставшиеся элементы) (defrule print-list (print-list $?list) > (progn$ (ч ?list) (if (<
    ?v-index 5) then (printout t ?v '™) else (printout t "...") (break)))
    (printout t crlf))J CLIPS> (reset)J CLIPS> (assert (print-list а b c d e))J CLIPS> (run)J a b c d e CLIPS> (assert (print-list а b c d e f g h))J CLIPS> (run)J a b c d e CLIPS> Функция Функция halt может использоваться в правой части любого правила для останова выполнения правил, находящихся в рабочем списке правил. Эта функция не требует параметров.
    После ее вызова прекращается выполнение каких-либо действий, заданных в правой части запущенного правила, и управление передается в приглашение верхнего уровня. В
    рабочем списке правил продолжают находиться все оставшиеся правила, активизированные ко времени вызова функции halt.
    788 Глава 10. Процедурное программирование Например, в правиле continue — check следующее действие (assert (phase halt)) можно было бы заменить таким действием, которое прекращает выполнение правил) Функция halt становится особенно удобной, если требуется прекратить выполнение программы после того, как пользователь выразит намерение снова вызвать в дальнейшем программу на выполнение с помощью команды run. Рассмотрим следующую модификацию правила continue-check: (defrule continue-check ?phase <- (phase check-continue) — > (retract ?phase) (printout t "Continue? ") (bind ?
    answer (read)) (while (and (песу ?answer yes) do (printout t
    "Continue? ") (bind ?answer (read))) (assert (phase continue)) (if
    (песу ?answer yes) then (halt))) (песу ?answer по) Конструкция de f f unction Язык CLIPS позволяет определять новые функции по такому же принципу, как ив других
    процедурных языках. Такие функции, применяемые наряду с правилами, позволяют уменьшить количество повторяющихся выражений ив левых, и правых частях. Новые функции определяются с использованием конструкции Конструкция беййыпсоп имеет следующий общий формат:
    Обратите внимание на то, что в этом правиле в список фактов вносится факт (phase continue ), невзирая на то, что ответил пользователь на вопрос о продолжении, "Continue? ". Внесение этого факта в список фактов приводит к тому, что в рабочий список правил помещаются правила, необходимые для продолжения выполнения. Если ответ на вопрос о продолжении не является положительным, то выполнение программы прекращается с помощью функции halt. После этого пользователь может проверить правила и факты, а затем снова перейти к выполнению программы с того места, где она была остановлена, воспользовавшись командой run.
    10.3. Конструкция de f f unction 789 (deffunction [] (* []) *) 2+2 2 В результате преобразования определим длину гипотенузы таким образом с Я+ь
    Преобразование этой формулы в конструкцию de f function приводит к получению следующего определения В этом определении параметр представляет собой однозначную переменную, а многозначную переменную. Имя конструкции def function, , должно быть уникальным, в частности, не должно совпадать с одной из уже существующих, заранее определенных функций CLIPS. Тело конструкции бей представленное параметром *, состоит из ряда выражений, подобных выражениям в правой части правила,
    которые выполняются последовательно при вызове конструкции def function. Определяемые пользователем конструкции de f function действуют аналогично заранее определенным функциям, предусмотренным в языке CLIPS. В любых условиях
    допускающих вызов заранее определенной системной функции, можно вызвать конструкцию def function. Нов отличие от заранее определенных функций, допускается удаление конструкций de f function, а для отслеживания их выполнения может использоваться команда watch. Объявления parameter> и позволяют задавать параметры, передаваемые в конструкцию def function при ее вызове. Такой способ вызова в определенной степени аналогичен активизации правил, если переменные, связанные со значениями в левой части правила, которые применяются в правой части правила, рассматриваются как объявления параметров. Кроме того, в теле конструкции de f f unction для создания локальных переменных может использоваться команда bind, в полном соответствии стем, как это действие выполняется в правой части правила. Конструкция de f function может возвращать значения, по аналогии стем, как возвращают значения некоторые заранее определенные функции.
    Возвращаемым значением конструкции de f f unction является значение последнего выражения, вычисленного в теле конструкции de f function. В качестве примера рассмотрим конструкцию def function, в которой вычисляется длина гипотенузы прямоугольного треугольника с помощью теоремы
    Пифагора. Допустим, что аи стороны, образующие прямой угол, а сгипотенуза. В таком случае согласно данной теореме можно записать следующее:
    Глава 10. Процедурное программирование 790 (deffunction hypotenuse-length (а ?b) (** (+ (* а а) (* Ь Ь) 0.5)) В данном случае значения длины сторон, прилегающих к прямому углу,
    равны 3 и 4, поэтому длина гипотенузы вычисляется правильно,
    как равная 5. Поскольку в конструкциях de f f unction можно использовать локальные переменные, применяемый способ вычисления длины гипотенузы можно представить в формате,

    1   ...   56   57   58   59   60   61   62   63   ...   74


    написать администратору сайта