Разница между логическим и функциональным программированием


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

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

8 63

8 ответов:

Я бы не сказал, что логика программирования определяет программы через математические выражения; это больше похоже на функциональное программирование. Логическое программирование использует логические выражения (ну, в конечном счете логика-это математика).

пролог, в частности, использует специальную форму логических предложений с именем пункты Рога!--17--> которые принадлежат логике первого порядка; Hilog использует предложения логики более высокого порядка.

при написании предиката пролога вы определяете предложение horn: foo :- bar1, bar2, bar3. означает, что foo истинно, если bar1, bar2 и bar3 истинно. заметить что Я не сказал, если и только если; вы можете иметь несколько предложений для одного предиката:

foo:-
   bar1.
foo:-
  bar2.

означает, что foo истинно, если bar1 истинно или если bar2 истинно

некоторые говорят, что логическое программирование является надмножеством функционального программирования, так как каждая функция может быть выражена в виде предиката:

foo(x,y) -> x+y.

может быть записан как

foo(X, Y, ReturnValue):-
   ReturnValue is X+Y.

но я думаю, что такие заявления немного вводят в заблуждение

еще одна разница между логикой и функционал отступает. В функциональном программировании после ввода тела функции вы не можете потерпеть неудачу и перейти к следующему определению. Например, вы можете написать

abs(x) -> 
   if x>0 x else -x

или даже использовать охранникам:

abs(x) x>0 -> x;
abs(x) x=<0 -> -x.

но ты не можешь писать

abs(x) ->
   x>0,
   x;
abs(x) ->
   -x.

С другой стороны, в прологе можно написать

abs(X, R):-
   X>0,
   R is X.
abs(X, R):-
   R is -X.

если вы называете abs(-3, R), Prolog попробует первое предложение и потерпит неудачу, когда выполнение достигнет -3 > 0 пункт но вы не получите сообщение об ошибке; Пролог будет пробовать второй пункт и вернуть R = 3.

Я не думаю, что функциональный язык не может реализовать что-то подобное (но я не использовал такой язык).

в двух словах:

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

factorial 0 = 1                       // a factorial of 0 is 1
factorial n = n * factorial (n - 1)   // a factorial of n is n times factorial of n - 1 

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

factorial(0, 1).               // it is true that a factorial of 0 is 1
factorial(X, Y) :-             // it is true that a factorial of X is Y, when all following are true:
    X1 is X - 1,                   // there is a X1, equal to X - 1,
    factorial(X1, Z),              // and it is true that factorial of X1 is Z, 
    Y is Z * X.                    // and Y is Z * X

оба стиля позволяют использовать математические выражения в программах.

во-первых, существует много общих черт между функциональным и логическим программированием. То есть многие понятия, выработанные в одном сообществе, могут быть использованы и в другом. Обе парадигмы начинались с довольно грубых реализаций и стремились к чистоте.

но вы хотите знать различия.

поэтому я возьму Haskell с одной стороны и пролог с ограничениями с другой. Практически все текущие системы пролога предлагают ограничения того или иного рода, например B, ЧАО, затмение, ГНУ, если, SICStus, сви, трепло, Активная приборная панель. Ради аргумента, я буду использовать очень простое ограничение dif/2 имеется в виду неравенство, которое присутствовало даже в самой первой реализации пролога - поэтому я не буду использовать ничего более продвинутого, чем это.

какого функционального программирования не хватает

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

> let v = iterate (tail) [1..3] 
> v
[[1,2,3],[2,3],[3],[],*** Exception: Prelude.tail: empty list

после 4-го элемента, значение неопределено. Тем не менее, вы можете безопасно использовать первые 4 элемента:

> take 4 v
[[1,2,3],[2,3],[3],[]]

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

в логическом программировании переменная не должна ссылаться на конкретное значение. Итак, если мы хотим список 3 элемента, можно сказать:

?- length(Xs,3).
Xs = [_G323, _G326, _G329].

в этом ответе элементы списка являются переменными. все возможные случаи этих переменных являются допустимыми решениями. Как Xs = [1,2,3]. Теперь, предположим, что первый элемент должен отличаться от остальных элементов:

?- length(Xs,3), Xs = [X|Ys], maplist(dif(X), Ys).
Xs = [X, _G639, _G642],
Ys = [_G639, _G642],
dif(X, _G642),
dif(X, _G639).

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

?- maplist(=(_),Xs).
Xs = [] ;
Xs = [_G231] ;
Xs = [_G231, _G231] ;
Xs = [_G231, _G231, _G231]  ;
Xs = [_G231, _G231, _G231, _G231] .

смотрите, что ответы содержат всегда одна и та же переменная? Теперь я могу объединить оба запроса:

?- length(Xs,3), Xs = [X|Ys], maplist(dif(X), Ys), maplist(=(_),Xs).
false.

Итак, мы показали здесь, что нет списка из 3 элементов, где первый элемент отличается от других элементов, и все элементы равны.

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

нет прямой способ получения аналогичной функциональности в функциональном программировании. Вы можете эмулировать вещи, но эмуляция не совсем то же самое.

какой логики программирования не хватает

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

Программирование высшего порядка: функциональное программирование имеет здесь очень давнюю традицию и разработало богатый набор идиом. Для Пролога, первые предложения датируются началом 1980-х годов, но до сих пор не очень распространены. По крайней мере, ISO Prolog теперь имеет гомолог для применения под названием call/2, call/3 ....

Lambdas: опять же, можно расширить логическое программирование в этом направлении, наиболее заметной системой является Лямда Пролог. Совсем недавно, лямбды были разработаны также Для ISO Prolog.

тип системы: были попытки, как Меркурий, но он не поймал на этом много. И нет система с функциональностью, сопоставимой с классами типов.

чистота: Haskell полностью чист, функция Integer - > Integer является функцией. Нет мелкого шрифта, скрывающегося вокруг. И все же вы можете выполнять побочные эффекты. Сопоставимые подходы развиваются очень медленно.

есть много областей, где функциональное и логическое программирование более или менее перекрываются. Например, отступление и лень и список понимания, ленивая оценка и freeze/2,when/2,block. DCGs и монады. Я оставлю обсуждение этих вопросов другим...

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

оба основаны на математических основаниях, которые обеспечивают больше преимуществ для "чистого" кода; код, который не работает с побочными эффектами. Есть языки для обеих парадигм, которые обеспечивают чистоту, а также языки, которые позволяют неограниченные побочные эффекты, но культурно программисты для таких языков, как правило, по-прежнему ценят чистоту.

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

в функциональном программировании, мы могли бы рассмотреть append будет что-то вроде этого:

append [] ys = ys
append (x:xs) ys = x : append xs ys

в то время как в логическом программировании, мы могли бы рассмотреть append быть что-то вот так:

append([], Ys, Ys).
append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).

они реализуют один и тот же алгоритм и даже работают в основном одинаково, но они "означают" что-то совсем другое.

функциональное append определяет список, который является результатом добавления ys на конец xs. Мы думаем о append как функция из двух списков в другой список, и система выполнения предназначена для вычисления результата функции, когда мы вызываем ее в двух списках.

логическое append определяет связь между тремя списками, которая является истинной, если третий список является элементами первого списка, за которыми следуют элементы второго списка. Мы думаем о append как это либо истина, либо ложь для любых 3 заданных списков, и система времени выполнения предназначена для поиска значений, которые сделают этот предикат истинным, когда мы вызываем его с некоторыми аргументами, привязанными к определенным спискам, а некоторые остаются несвязанными.

то, что делает логичным append другой вы можете использовать его для вычисления списка, который получается в результате добавления одного списка на другой, но вы можете и используйте его для вычисления списка, который вам нужно будет добавить в конец другого, чтобы получить третий список (или нет ли такого списка),или чтобы вычислить список, к которому нужно добавить еще один, чтобы получить третий список,или чтобы дать вам два возможных списка, которые могут быть добавлены вместе, чтобы получить данный третий (и изучить все возможные способы сделать этот.)

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

Пролог, будучи логическим языком, дает вам свободное отступление, это довольно заметно.

чтобы уточнить, и я уточняю, что я никоим образом не эксперт ни в одной из парадигм, мне кажется, что логическое программирование намного лучше, когда дело доходит до решения вещей. Потому что это именно то, что делает язык (это ясно проявляется, когда требуется, например, отступление).

Я думаю, что разница такая:

  • императивное Программирование=моделирование действий
  • Программирование функций=моделирование рассуждений
  • логическое программирование =моделирование знаний

выбрать то, что подходит вашему уму лучшие

функциональное программирование: когда 6 вечера, свет. логическое программирование: когда темно, свет включен.

разница между функциональным и императивным программированием основана на двух понятиях: -

a: - Что делать ? Б:- как это сделать ?

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