Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Еремеев А.П., Чибизова Н.В. Методическое пособие по курсу «Экспертные системы».doc
Скачиваний:
82
Добавлен:
02.05.2014
Размер:
1.32 Mб
Скачать
      1. Листинг программы

Ниже приведен листинг программы, снабженный пояснениями (пояснения не оформлены в виде комментариев CLIPS для удобства чтения).

Класс коксовой камеры:

(defclass koks

(is-a USER)

(role concrete)

(pattern-match reactive)

(slot rashod_syria1 (type SYMBOL)(create-accessor read-write) (visibility public))

(slot temp_na_vhode (type SYMBOL)(create-accessor read-write) (visibility public))

(slot koksuemost (type SYMBOL)(create-accessor read-write) (visibility public))

(slot koef_recircul (type SYMBOL)(create-accessor read-write) (visibility public))

)

Класс ректификационной колонны:

(defclass colonna

(is-a USER)

(role concrete)

(pattern-match reactive)

(slot rashod_syria2 (type SYMBOL)(create-accessor read-write) (visibility public))

(slot rashod_ostr_orosh (type SYMBOL)(create-accessor read-write) (visibility public))

(slot rashod_circ_orosh (type SYMBOL)(create-accessor read-write) (visibility public))

(slot temp_peretoka (type SYMBOL)(create-accessor read-write) (visibility public))

)

Потомок классов коксовой камеры и ректификационной колонны с дополни­тель­но оп­ре­де­лен­ным параметром temp_pechi, определяющим температу­ру печей первичного сырья:

(defclass U_Z_K

(is-a colonna koks)

(role concrete)

(pattern-match reactive)

(slot temp_pechi (type SYMBOL)(create-accessor read-write))

(slot answer (type SYMBOL)(create-accessor read-write))

)

Объект класса U_Z_K:

(definstances Ustanovka

(uzk of U_Z_K

(rashod_syria1 ln)

(koksuemost ln)

(koef_recircul ln)

(temp_na_vhode n)

(rashod_syria2 mn)

(rashod_ostr_orosh mn)

(rashod_circ_orosh ln)

(temp_peretoka lln)

(temp_pechi n)

(answer ln)

))

Шаблон для промежуточных результатов проверки:

(deftemplate provUZK

(field provereno (type SYMBOL)(default net))

(field resultatCam (type SYMBOL)(default net))

(field resultatCol (type SYMBOL)(default net))

)

Шаблон для результатов работы:

(deftemplate ResRaboty

(field vyhod_letuch (type SYMBOL)(default net))

(field kach_benzina (type SYMBOL)(default net))

)

Правило, которое связывается с initial-fact (всегда есть в системе по умолчанию), выполняется при запуске программы:

(defrule zapusk (initial-fact) => (assert (provUZK))(assert (ResRaboty)) (send [uzk] vopros))

Печать вопросов и получение ответов пользователя для формирования решения:

(defmessage-handler U_Z_K vopros()

(printout t crlf «Программа по определению качества работы установки замедленного коксования.»)

(printout t crlf «Для ответа на вопрос наберите одно из значений »)

(printout t crlf «ln (ниже нормы),lln (чуть ниже нормы),n (в норме),lmn (чуть выше нормы), mn (выше нормы)» t crlf)

(send [uzk] vopros1 rashod_syria1 «Какой расход сырья в коксовых камерах? -> »)

(send [uzk] vopros1 koksuemost «Какова коксуемость в коксовых камерах? -> »)

(send [uzk] vopros1 koef_recircul «Каков коэффициент рециркуляции в коксовых камерах? ->»)

(send [uzk] vopros1 temp_na_vhode «Какова температура на входе в коксовые камеры? -> »)

(send [uzk] vopros1 rashod_syria2 «Какой расход сырья в ректификационной колонне? -> »)

(send [uzk] vopros1 rashod_ostr_orosh «Каков расход острого орошения в ректификационной колонне? -> »)

(send [uzk] vopros1 rashod_circ_orosh «Каков расход циркуляционного орошения в ректификационной колонне? -> »)

(send [uzk] vopros1 temp_peretoka «Какова температура перетока в ректификационной колонне? -> »)

(send [uzk] vopros1 temp_pechi «Какова температура основной печи? -> »)

)

(defmessage-handler U_Z_K vopros1(?ab ?bc)

(printout t crlf ?bc)

(dynamic-put answer (read))

(if (or (eq (dynamic-get answer) ln)

(eq (dynamic-get answer) lln)

(eq (dynamic-get answer) n)

(eq (dynamic-get answer) lmn)

(eq (dynamic-get answer) mn)

)

then (dynamic-put ?ab (dynamic-get answer))

else (send [uzk] vopros1 ?ab ?bc)

))

Проверка температуры печи:

(defmessage-handler U_Z_K poriadok()

(if (or (eq (dynamic-get temp_pechi) lln)

(eq (dynamic-get temp_pechi) n)

(eq (dynamic-get temp_pechi) lmn)

)

then TRUE

else

(printout t crlf «Температура не подходит для начала работы!» t crlf)

FALSE

))

(defrule nachalo

?rr <- (provUZK (provereno net)) =>

(if (eq (send [uzk] poriadok) TRUE)

then

(send [uzk] pechat) (modify ?rr (provereno da))

))

Вывод на экран параметров (введенных и полученных на основе введенных):

(defmessage-handler U_Z_K pechat()

(printout t crlf «Параметры для расчета качества кокса, полученного в коксовых камерах:» t)

(printout t «Расход сырья»)

(if (eq (dynamic-get rashod_syria1) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get rashod_syria1) lln)

then (printout t «чуть ниже нормы» t )

else

(if (eq (dynamic-get rashod_syria1) n)

then (printout t «в норме» t )

else

(if (eq (dynamic-get rashod_syria1) lmn)

then (printout t «чуть выше нормы» t)

else (printout t «выше нормы» t)

))))

(printout t «Температура на входе»)

(if (eq (dynamic-get temp_na_vhode) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get temp_na_vhode) lln)

then (printout t «чуть ниже нормы» t )

else

(if (eq (dynamic-get temp_na_vhode) n)

then (printout t «в норме» t )

else

(if (eq (dynamic-get temp_na_vhode) lmn)

then (printout t «чуть выше нормы» t)

else (printout t «выше нормы» t )

))))

(printout t «Коксуемость»)

(if (eq (dynamic-get koksuemost) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get koksuemost) lln)

then (printout t «чуть ниже нормы» t)

else

(if (eq (dynamic-get koksuemost) n)

then (printout t «в норме» t)

else

(if (eq (dynamic-get koksuemost) lmn)

then (printout t «чуть выше нормы» t )

else (printout t «выше нормы» t )

))))

(printout t «Коэффициент рециркуляции»)

(if (eq (dynamic-get koef_recircul) ln)

then (printout t «ниже нормы» t crlf)

TRUE

else

(if (eq (dynamic-get koef_recircul) lln)

then (printout t «чуть ниже нормы» t crlf)

else

(if (eq (dynamic-get koef_recircul) n)

then (printout t «в норме» t crlf)

else

(if (eq (dynamic-get koef_recircul) lmn)

then (printout t «чуть выше нормы» t crlf)

else (printout t «выше нормы» t crlf)

))))

(printout t crlf «Параметры для расчета качества бензина, полученного в ректификационной колонне:» t)

(printout t «Расход сырья»)

(if (eq (dynamic-get rashod_syria2) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get rashod_syria2) lln)

then (printout t «чуть ниже нормы» t)

else

(if (eq (dynamic-get rashod_syria2) n)

then (printout t «в норме» t)

else

(if (eq (dynamic-get rashod_syria2) lmn)

then (printout t «чуть выше нормы» t)

else (printout t «выше нормы» t )

))))

(printout t «Расход острого орошения»)

(if (eq (dynamic-get rashod_ostr_orosh) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get rashod_ostr_orosh) lln)

then (printout t «чуть ниже нормы» t)

else

(if (eq (dynamic-get rashod_ostr_orosh) n)

then (printout t «в норме» t)

else

(if (eq (dynamic-get rashod_ostr_orosh) lmn)

then (printout t «чуть выше нормы» t)

else (printout t «выше нормы» t )

))))

(printout t «Расход циркуляционного орошения»)

(if (eq (dynamic-get rashod_circ_orosh) ln)

then (printout t «ниже нормы» t)

TRUE

else

(if (eq (dynamic-get rashod_circ_orosh) lln)

then (printout t «чуть ниже нормы» t)

else

(if (eq (dynamic-get rashod_circ_orosh) n)

then (printout t «в норме» t)

else

(if (eq (dynamic-get rashod_circ_orosh) lmn)

then (printout t «чуть выше нормы» t)

else (printout t «выше нормы» t)

))))

(printout t «Температура перетока»)

(if (eq (dynamic-get temp_peretoka) ln)

then (printout t «ниже нормы» t crlf)

TRUE

else

(if (eq (dynamic-get temp_peretoka) lln)

then (printout t «чуть ниже нормы» t crlf)

else

(if (eq (dynamic-get temp_peretoka) n)

then (printout t «в норме» t crlf)

else

(if (eq (dynamic-get temp_peretoka) lmn)

then (printout t «чуть выше нормы» t crlf)

else (printout t «выше нормы» t crlf)

))))

)

Правила, по которым определяется выход летучих фракций:

(defrule VyhLetuchS

(and (or

(object (name [uzk]) (koef_recircul ln)(koksuemost ln))

(object (name [uzk]) (koef_recircul ln)(koksuemost n)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul ln)(koksuemost lln))

(object (name [uzk]) (koef_recircul n)(koksuemost ln)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul lln)(koksuemost ln))

(object (name [uzk]) (koef_recircul n)(koksuemost lln)(rashod_syria1 ln) (temp_na_vhode ln))

(object (name [uzk]) (koef_recircul lln)(koksuemost lln)(rashod_syria1 ln) (temp_na_vhode ln))

(object (name [uzk]) (koef_recircul lln)(koksuemost n)(rashod_syria1 ln) (temp_na_vhode ln))

)

?p1 <- (ResRaboty (vyhod_letuch net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (vyhod_letuch s) ) (printout t «Плохое качество кокса!» crlf)

)

(defrule VyhLetuchLS

(and (or

(object (name [uzk]) (koef_recircul ln)(koksuemost n))

(object (name [uzk]) (koef_recircul ln)(koksuemost lmn))

(object (name [uzk]) (koef_recircul ln)(koksuemost mn)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul lln)(koksuemost n))

(object (name [uzk]) (koef_recircul n)(koksuemost ln))

(object (name [uzk]) (koef_recircul n)(koksuemost lln)(rashod_syria1 lln))

(object (name [uzk]) (koef_recircul n)(koksuemost lln)(rashod_syria1 n))

)

?p1 <- (ResRaboty (vyhod_letuch net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (vyhod_letuch ls))

(printout t «Качество кокса ниже среднего!» crlf)

)

(defrule VyhLetuchLB

(and (or

(object (name [uzk]) (koef_recircul mn)(koksuemost n))

(object (name [uzk]) (koef_recircul mn)(koksuemost lln))

(object (name [uzk]) (koef_recircul mn)(koksuemost ln)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul lmn)(koksuemost lmn))

(object (name [uzk]) (koef_recircul lmn)(koksuemost n))

(object (name [uzk]) (koef_recircul n)(koksuemost mn))

(object (name [uzk]) (koef_recircul n)(koksuemost lmn)(rashod_syria1 lmn))

(object (name [uzk]) (koef_recircul n)(koksuemost lmn)(rashod_syria1 n))

)

?p1 <- (ResRaboty (vyhod_letuch net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (vyhod_letuch lb)) (printout t «Хорошее качество кокса!» crlf)

)

(defrule VyhLetuchB

(and (or

(object (name [uzk]) (koef_recircul mn)(koksuemost mn))

(object (name [uzk]) (koef_recircul mn)(koksuemost n)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul mn)(koksuemost lmn))

(object (name [uzk]) (koef_recircul n)(koksuemost mn)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul lmn)(koksuemost mn))

(object (name [uzk]) (koef_recircul n)(koksuemost lmn)(rashod_syria1 mn) (temp_na_vhode mn))

(object (name [uzk]) (koef_recircul lmn)(koksuemost lmn)(rashod_syria1 mn) (temp_na_vhode mn))

(object (name [uzk]) (koef_recircul lmn)(koksuemost n)(rashod_syria1 mn) (temp_na_vhode mn))

)

?p1 <- (ResRaboty (vyhod_letuch net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (vyhod_letuch b)) (printout t «Отличное качество кокса!» crlf)

)

(defrule VyhLetuchM

(and (or

(not (object (name [uzk]) (koef_recircul ln)(koksuemost mn) (rashod_syria1 ln)))

(object (name [uzk]) (koef_recircul ln)(koksuemost mn))

(object (name [uzk]) (koef_recircul lln)(koksuemost lln)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul lln)(koksuemost n)(rashod_syria1 lmn))

(object (name [uzk]) (koef_recircul lln)(koksuemost n)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul lln)(koksuemost lmn))

(object (name [uzk]) (koef_recircul lln)(koksuemost mn))

(object (name [uzk]) (koef_recircul n)(koksuemost ln)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul n)(koksuemost lln)(rashod_syria1 lmn))

(object (name [uzk]) (koef_recircul n)(koksuemost lln)(rashod_syria1 mn))

(object (name [uzk]) (koef_recircul n)(koksuemost n))

(not (object (name [uzk]) (koef_recircul mn)(koksuemost ln) (rashod_syria1 mn)))

(object (name [uzk]) (koef_recircul mn)(koksuemost ln))

(object (name [uzk]) (koef_recircul lmn)(koksuemost lmn)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul lmn)(koksuemost n)(rashod_syria1 lln))

(object (name [uzk]) (koef_recircul lmn)(koksuemost n)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul lmn)(koksuemost lln))

(object (name [uzk]) (koef_recircul lmn)(koksuemost ln))

(object (name [uzk]) (koef_recircul n)(koksuemost mn)(rashod_syria1 ln))

(object (name [uzk]) (koef_recircul n)(koksuemost lmn)(rashod_syria1 lln))

(object (name [uzk]) (koef_recircul n)(koksuemost lmn)(rashod_syria1 ln))

)

?p1 <- (ResRaboty ( vyhod_letuch net))

?p2 <- (provUZK (provereno da)))

=> (printout t «Среднее качество кокса» crlf)(modify ?p1 (vyhod_letuch m))

)

Правила, по которым определяется качество бензина:

(defrule KachBenzS

(and (or

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh ln))

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh n) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh lln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh ln) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh ln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lln) (rashod_syria2 ln) (temp_peretoka ln))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh lln) (rashod_syria2 ln)(temp_peretoka ln))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh n) (rashod_syria2 ln) (temp_peretoka ln))

)

?p1 <- (ResRaboty (kach_benzina net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (kach_benzina s)) (printout t «Плохое качество бензина!» crlf)

)

(defrule KachBenzB

(and (or

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh mn))

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh n) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh lmn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh mn) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh mn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lmn) (rashod_syria2 mn)(temp_peretoka mn))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh lmn) (rashod_syria2 mn)(temp_peretoka mn))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh n) (rashod_syria2 mn) (temp_peretoka mn))

)

?p1 <- (ResRaboty (kach_benzina net))

?p2 <- (provUZK (provereno da)))

=>(modify ?p1 (kach_benzina b))(printout t «Отличное качество бензина!» crlf)

)

(defrule KachBenzLS

(and (or

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh n)) (object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh lmn))

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh mn) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh lln))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh n))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh ln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lln) (rashod_syria2 lln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lln) (rashod_syria2 n))

)

?p1 <- (ResRaboty (kach_benzina net))

?p2 <- (provUZK (provereno da)))

=> (modify ?p1 (kach_benzina ls)) (printout t «Качество бензина ниже среднего!» crlf)

)

(defrule KachBenzLB

(and (or

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh n))

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh lln))

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh ln) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh lmn))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh n))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh mn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lmn) (rashod_syria2 lmn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lmn) (rashod_syria2 n))

)

?p1 <- (ResRaboty (kach_benzina net))

?p2 <- (provUZK (provereno da)))

=>(modify ?p1 (kach_benzina lb))(printout t «Хорошее качество бензина!» crlf)

)

(defrule KachBenzM

(and (or

(not (object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh mn) (rashod_syria2 ln)))

(object (name [uzk]) (rashod_ostr_orosh ln)(rashod_circ_orosh mn))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh lln) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh n) (rashod_syria2 lmn))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh n) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh lmn))

(object (name [uzk]) (rashod_ostr_orosh lln)(rashod_circ_orosh mn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh ln) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lln) (rashod_syria2 lmn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lln) (rashod_syria2 mn))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh n))

(not (object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh ln) (rashod_syria2 mn)))

(object (name [uzk]) (rashod_ostr_orosh mn)(rashod_circ_orosh ln))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh lmn) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh n) (rashod_syria2 lln))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh n) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh lln))

(object (name [uzk]) (rashod_ostr_orosh lmn)(rashod_circ_orosh ln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh mn) (rashod_syria2 ln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lmn) (rashod_syria2 lln))

(object (name [uzk]) (rashod_ostr_orosh n)(rashod_circ_orosh lmn) (rashod_syria2 ln))

)

?p1 <- (ResRaboty (kach_benzina net))

?p2 <- (provUZK (provereno da)))

=> (printout t «Среднее качество бензина» crlf)(modify ?p1 (kach_benzina m)))

Вывод результатов работы:

(defrule ItogRaboty

(ResRaboty (vyhod_letuch ?l)(kach_benzina ?k))=>(send [uzk] NewResult ?l ?k)

)

(defmessage-handler U_Z_K NewResult (?l ?k)

(if (or (eq ?l net) (eq ?k net))

then FALSE

else

(if (or

(and (eq ?l s) (eq ?k s))

(and (eq ?l ls) (eq ?k s))

(and (eq ?l s) (eq ?k ls))

(and (eq ?l s) (eq ?k m))

(and (eq ?l m) (eq ?k s))

)

then (printout t «Плохая работа установки!» crlf)

else

(if (or

(and (eq ?l ls) (eq ?k ls))

(and (eq ?l m) (eq ?k m))

(and (eq ?l lb) (eq ?k lb))

(and (eq ?l ls) (eq ?k m))

(and (eq ?l m) (eq ?k ls))

(and (eq ?l lb) (eq ?k m))

(and (eq ?l lb) (eq ?k m))

(and (eq ?l b) (eq ?k ls))

(and (eq ?l ls) (eq ?k b))

)

then (printout t «Нормальная работа установки» crlf)

else

(if (or

(and (eq ?l b) (eq ?k b))

(and (eq ?l b) (eq ?k lb))

(and (eq ?l lb) (eq ?k b))

(and (eq ?l b) (eq ?k m))

(and (eq ?l m) (eq ?k b))

)

then (printout t «Хорошая работа установки»crlf)

else (printout t «Установка плохо вырабатывает один из компонентов» crlf)

)))))

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.