stringtranslate.com

Декларативное программирование

В информатике декларативное программирование — это парадигма программирования — стиль построения структуры и элементов компьютерных программ , — которая выражает логику вычисления без описания его потока управления . [1]

Многие языки, применяющие этот стиль, пытаются минимизировать или устранить побочные эффекты , описывая то, что программа должна выполнить в терминах проблемной области , а не описывая, как это выполнить, как последовательность примитивов языка программирования [2] ( как остается на усмотрение реализации языка ). Это контрастирует с императивным программированием , которое реализует алгоритмы явными шагами. [3] [4]

Декларативное программирование часто рассматривает программы как теории формальной логики , а вычисления как выводы в этом логическом пространстве. Декларативное программирование может значительно упростить написание параллельных программ . [5]

К распространенным декларативным языкам относятся языки запросов к базам данных (например, SQL , XQuery ), регулярные выражения , логическое программирование (например, Prolog , Datalog , программирование наборов ответов ), функциональное программирование , управление конфигурацией и системы алгебраического моделирования .

Определение

Декларативное программирование часто определяется как любой стиль программирования, который не является императивным. Ряд других распространенных определений пытаются определить его, просто противопоставляя его императивному программированию. Например:

Эти определения во многом пересекаются.

Декларативное программирование — это неимперативный стиль программирования, в котором программы описывают желаемые результаты без явного перечисления команд или шагов, которые должны быть выполнены. Функциональные и логические языки программирования характеризуются декларативным стилем программирования. В логическом программировании программы состоят из предложений, выраженных в логической форме, а вычисления используют эти предложения для решения задач, которые также выражены в логической форме.

В чисто функциональном языке , таком как Haskell , все функции не имеют побочных эффектов , а изменения состояния представлены только как функции, преобразующие состояние, которое явно представлено как объект первого класса в программе. Хотя чисто функциональные языки не являются императивными, они часто предоставляют возможность описывать эффект функции как последовательность шагов. Другие функциональные языки, такие как Lisp , OCaml и Erlang , поддерживают смесь процедурного и функционального программирования.

Некоторые языки логического программирования, такие как Prolog , и языки запросов к базам данных, такие как SQL, хотя и являются декларативными по своей сути, также поддерживают процедурный стиль программирования.

Субпарадигмы

Декларативное программирование — это обобщающий термин , включающий в себя ряд наиболее известных парадигм программирования .

Программирование ограничений

Программирование в ограничениях устанавливает отношения между переменными в форме ограничений, которые определяют свойства целевого решения. Набор ограничений решается путем присвоения значения каждой переменной, чтобы решение соответствовало максимальному количеству ограничений. Программирование в ограничениях часто дополняет другие парадигмы: функциональное, логическое или даже императивное программирование.

Языки, специфичные для домена

Известные примеры декларативных предметно-ориентированных языков (DSL) включают в себя язык ввода генератора парсеров yacc , QML , язык спецификации сборки Make , язык управления конфигурацией Puppet, регулярные выражения , Datalog , программирование наборов ответов и подмножество SQL (например, запросы SELECT). DSL имеют то преимущество, что они полезны, не обязательно должны быть полными по Тьюрингу , что упрощает для языка возможность быть чисто декларативным.

Многие языки разметки, такие как HTML , MXML , XAML , XSLT или другие языки разметки пользовательского интерфейса, часто являются декларативными. HTML, например, описывает только то, что должно отображаться на веб-странице — он не определяет ни поток управления для рендеринга страницы, ни возможные взаимодействия страницы с пользователем .

По состоянию на 2013 год некоторые программные системы [ которые? ] объединяют традиционные языки разметки пользовательского интерфейса (такие как HTML) с декларативной разметкой, которая определяет, что (но не как) должны делать внутренние серверные системы для поддержки заявленного интерфейса. Такие системы, как правило, использующие доменно-специфическое пространство имен XML , могут включать абстракции синтаксиса базы данных SQL или параметризованные вызовы веб-сервисов с использованием передачи репрезентативного состояния (REST) ​​и SOAP . [ необходима цитата ]

Функциональное программирование

Функциональные языки программирования, такие как Haskell , Scheme и ML, оценивают выражения через применение функций. В отличие от связанной, но более императивной парадигмы процедурного программирования , функциональное программирование уделяет мало внимания явному упорядочиванию. Вместо этого вычисления характеризуются различными видами рекурсивного применения и композиции функций высшего порядка , и как таковые могут рассматриваться просто как набор отображений между доменами и кодоменами . Многие функциональные языки, включая большинство языков семейств ML и Lisp, не являются чисто функциональными и, таким образом, позволяют вводить в программы эффекты с сохранением состояния .

Гибридные языки

Например, файлы Makefiles определяют зависимости декларативным образом, [7] , но также включают императивный список действий, которые необходимо предпринять. Аналогично, yacc определяет контекстно-свободную грамматику декларативно, но включает фрагменты кода из языка-хоста, который обычно является императивным (например, C ).

Логическое программирование

Языки логического программирования, такие как Prolog , Datalog и программирование набора ответов , выполняют вычисления, доказывая, что цель является логическим следствием программы, или показывая, что цель истинна в модели, определенной программой. Prolog выполняет вычисления, сводя цели к подцелям, сверху вниз, используя обратные рассуждения , тогда как большинство систем Datalog выполняют вычисления снизу вверх, используя прямые рассуждения . Программы набора ответов обычно используют решатели SAT для генерации модели программы.

Моделирование

Модели или математические представления физических систем могут быть реализованы в компьютерном коде, который является декларативным. Код содержит ряд уравнений, а не императивных назначений, которые описывают («декларируют») поведенческие отношения. Когда модель выражается в этом формализме, компьютер способен выполнять алгебраические манипуляции, чтобы наилучшим образом сформулировать алгоритм решения. Математическая причинность обычно накладывается на границы физической системы, в то время как поведенческое описание самой системы является декларативным или акаузальным. Декларативные языки моделирования и среды включают Analytica , Modelica и Simile. [8]

Примеры

Лисп

Lisp — это семейство языков программирования, в основе которого лежат математические обозначения и лямбда-исчисление Алонзо Чёрча . Некоторые диалекты, такие как Common Lisp , в первую очередь императивные, но поддерживают функциональное программирование. Другие, такие как Scheme , предназначены для функционального программирования.

В Схеме факториальную функцию можно определить следующим образом:

( определить ( факториал n ) ( если ( = n 0 ) 1 ;;; 0! = 1 ( * n ( факториал ( - n 1 ))))) ;;; n! = n*(n-1)!                

Это определяет функцию факториала, используя ее рекурсивное определение. Напротив, более типично определять процедуру для императивного языка.

В lisp и лямбда-исчислении функции обычно являются гражданами первого класса . Грубо говоря, это означает, что функции могут быть входами и выходами для других функций. Это может упростить определение некоторых функций.

Например, написать функцию для вывода первых n квадратных чисел в Racket можно следующим образом:

( define ( first-n-squares n ) ( map ( lambda ( x ) ( * x x )) ;;; Функция, отображающая x -> x^2 ( range n ))) ;;; Список первых n неотрицательных целых чисел            

Функция map принимает функцию и список; на выходе получается список результатов функции ввода для каждого элемента списка ввода.

МЛ

ML (1973) [9] означает «Meta Language». ML является статически типизированным, а аргументы функций и возвращаемые типы могут быть аннотированы. [10]

развлечение_10  ( n : int ) : int = 10 * n ;        

ML не так сильно ориентирован на скобки, как Lisp , и вместо этого использует более широкий спектр синтаксиса для кодификации отношений между элементами кода, а не апеллирует к упорядочиванию списков и вложенности для выражения всего. Ниже приведен пример применения times_10:

раз_10 2

Возвращает «20 : int», то есть 20значение типа int.

Как и Lisp , ML предназначен для обработки списков, хотя все элементы списка должны быть одного типа. [11]


Пролог

Prolog (1972) означает «PROprogramming in LOGic». Он был разработан для ответов на вопросы на естественном языке [12] с использованием разрешения SL [13] как для вывода ответов на запросы, так и для анализа и генерации предложений на естественном языке.

Строительными блоками программы Prolog являются факты и правила . Вот простой пример:

кот ( том ).  % том — кот, мышь ( джерри ) .  % джерри — мышьживотное ( X )  :-  кошка ( X ).  % каждая кошка является животным животное ( X )  :-  мышь ( X ).  % каждая мышь является животнымбольшой ( X )  :-  кот ( X ).  % каждый кот большой маленький ( X )  :-  мышь ( X ).  % каждая мышь маленькаяешьте ( X , Y )  :-  мышь ( X ),  сыр ( Y ).  % каждая мышь ест каждый сыр ешьте ( X , Y )  :-  большой ( X ),  маленький ( Y ).  % каждое большое существо ест каждое маленькое существо

При наличии этой программы запрос выполняется успешно, а не выполняется. Более того, запрос выполняется успешно с заменой ответа .eat(tom,jerry)eat(jerry,tom)eat(X,jerry)X=tom

Prolog выполняет программы сверху вниз, используя разрешение SLD для рассуждений в обратном порядке , сводя цели к подцелям. В этом примере он использует последнее правило программы, чтобы свести цель ответа на запрос к подцелям сначала найти X, такой что выполняется, а затем показать, что выполняется. Он многократно использует правила для дальнейшего сведения подцелей к другим подцелям, пока в конечном итоге не преуспеет в объединении всех подцелей с фактами в программе. Эта стратегия обратного рассуждения и сведения цели рассматривает правила в логических программах как процедуры и делает Prolog как декларативным, так и процедурным языком программирования . [14]eat(X,jerry)big(X)small(jerry)

Широкий спектр приложений Prolog освещается в книге «Год Prolog» [15] , посвященной 50-летию Prolog.

Журнал данных

Истоки Datalog восходят к началу логического программирования, но он был идентифицирован как отдельная область около 1977 года. Синтаксически и семантически он является подмножеством Prolog. Но поскольку он не имеет составных терминов , он не является полным по Тьюрингу .

Большинство систем Datalog выполняют программы снизу вверх, используя правила для рассуждений вперед , выводя новые факты из существующих фактов и завершая работу, когда нет новых фактов, которые можно вывести, или когда выведенные факты унифицируются с запросом. В приведенном выше примере типичная система Datalog сначала выводит новые факты:

животное ( том ). животное ( джерри ). большой ( том ). маленький ( джерри ).

Используя эти факты, он затем выведет дополнительный факт:

ест ( том ,  джерри ).

Затем он будет завершен, как потому, что не может быть получено никаких новых дополнительных фактов, так и потому, что вновь полученный факт объединяется с запросом.

ест ( X ,  Джерри ).

Datalog применяется к таким проблемам, как интеграция данных , извлечение информации , сетевое взаимодействие , безопасность , облачные вычисления и машинное обучение . [16] [17]

Программирование набора ответов

Программирование набора ответов (ASP) развилось в конце 1990-х годов на основе стабильной модели (набора ответов) семантики логического программирования. Как и Datalog, это подмножество Prolog; и, поскольку в нем нет составных терминов, он не является полным по Тьюрингу.

Большинство реализаций ASP выполняют программу, сначала «заземляя» ее, заменяя все переменные в правилах константами всеми возможными способами, а затем используя пропозициональный решатель SAT, такой как алгоритм DPLL , для генерации одной или нескольких моделей программы.

Его приложения ориентированы на решение сложных задач поиска и представления знаний . [18] [19]

Смотрите также

Ссылки

  1. ^ Ллойд, Дж. У., Практические преимущества декларативного программирования.
  2. ^ "декларативный язык". FOLDOC . 17 мая 2004 г. Архивировано из оригинала 7 сентября 2023 г. Получено 7 сентября 2023 г.
  3. ^ Sebesta, Robert (2016). Концепции языков программирования . Бостон: Pearson. ISBN 978-0-13-394302-3. OCLC  896687896.
  4. ^ "Императивное программирование: Обзор старейшей парадигмы программирования". IONOS Digital Guide . 2021-05-21. Архивировано из оригинала 2022-05-03 . Получено 2023-05-23 .
  5. ^ "DAMP 2009: Workshop on Declarative Aspects of Multicore Programming". Cse.unsw.edu.au. 20 января 2009 г. Архивировано из оригинала 13 сентября 2013 г. Получено 15 августа 2013 г.
  6. ^ Чакраварти, Мануэль МТ (14 февраля 1997 г.). О массовом параллельном выполнении декларативных программ (докторская диссертация). Технический университет Берлина . Архивировано из оригинала 23 сентября 2015 г. Получено 26 февраля 2015 г. В этом контексте критерием для обозначения языка программирования как декларативного является существование четкого, математически установленного соответствия между языком и математической логикой, такого, что декларативная семантика для языка может быть основана на модели или теории доказательств (или на обеих) логики.
  7. ^ "Обзор dsls". Архивировано из оригинала 23 октября 2007 г.
  8. ^ "Декларативное моделирование". Симулистика. Архивировано из оригинала 11 августа 2003 года . Получено 15 августа 2013 года .
  9. ^ Гордон, Майкл Дж. К. (1996). «От LCF к HOL: краткая история». Архивировано из оригинала 2016-09-05 . Получено 2021-10-30 .
  10. ^ Уилсон, Лесли Б. (2001). Сравнительные языки программирования, третье издание . Addison-Wesley. стр. 233. ISBN 0-201-71012-9.
  11. ^ Уилсон, Лесли Б. (2001). Сравнительные языки программирования, третье издание . Addison-Wesley. стр. 235. ISBN 0-201-71012-9.
  12. ^ "Рождение Пролога" (PDF) . Ноябрь 1992. Архивировано (PDF) из оригинала 2015-04-02 . Получено 2022-05-25 .
  13. ^ Роберт Ковальски; Дональд Кюнер (зима 1971 г.). «Линейное разрешение с функцией выбора» (PDF) . Искусственный интеллект . 2 (3–4): 227–260. doi :10.1016/0004-3702(71)90012-9. ISSN  0004-3702. Архивировано (PDF) из оригинала 2015-09-23 . Получено 2023-08-13 .
  14. ^ Роберт Ковальски Предикатная логика как язык программирования. Архивировано 7 февраля 2016 г. в Wayback Machine Memo 70, кафедра искусственного интеллекта, Эдинбургский университет. 1973. Также в трудах Конгресса IFIP, Стокгольм, North Holland Publishing Co., 1974, стр. 569-574.
  15. ^ Warren, DS (2023). «Введение в Prolog». В Warren, DS; Dahl, V.; Eiter, T.; Hermenegildo, MV; Kowalski, R.; Rossi, F. (ред.). Prolog: The Next 50 Years . Lecture Notes in Computer Science(). Vol. 13900. Springer, Cham. стр. 3–19. doi :10.1007/978-3-031-35254-6_1. ISBN 978-3-031-35253-9.
  16. ^ Хуан, Шань Шань; Грин, Тодд Дж.; Лу, Бун Тау (12–16 июня 2011 г.). Datalog и новые приложения (PDF) . SIGMOD 2011. Афины, Греция: Ассоциация вычислительной техники. ISBN 978-1-4503-0661-4. Архивировано (PDF) из оригинала 2020-10-22 . Получено 2023-08-13 .
  17. ^ Мэй, Хунъюань; Цинь, Гуанхуэй; Сюй, Миньцзе; Эйснер, Джейсон (2020). «Нейронный даталог во времени: обоснованное временное моделирование с помощью логической спецификации». Труды ICML 2020. arXiv : 2006.16723 .
  18. ^ Барал, Читта (2003). Представление знаний, рассуждения и декларативное решение проблем . Cambridge University Press. ISBN 978-0-521-81802-5.
  19. ^ Гельфонд, Майкл (2008). «Наборы ответов». В ван Хармелен, Франк; Лифшиц, Владимир; Портер, Брюс (ред.). Справочник по представлению знаний . Elsevier. стр. 285–316. ISBN 978-0-08-055702-1.в формате PDF Архивировано 2016-03-03 на Wayback Machine

Внешние ссылки