Пролог как бесперспективное заблуждение

Быть может, я недостаточно известен своей нелюбовью к прологу, нечёткой логике в двух ипостасях и ещё чему-то. Надо это подправить.

Изначально неплохая идея дизъюнктов Хорна испорчена сечениями. Изначально неплохая идея описательного языка испорчена претензиями на возможность притянуть его к императивности. Да ещё надо уметь эту императивность описать правильно. В результате чтобы написать что-то правильно вычисляющееся, не уходящее в бесконечное ожидание ответа, надо перестроить свой разум, и даже после этого его КПД не будет желаемым. Да и не тянет такая перестройка на упорядочение фактов в голове совсем — наоборот, приходится постоянно помнить о всех ухопритяжениях, чтобы код был корректным.

Пролог без типов? Лисп лучше. Пролог с типами? Хаскель лучше.

(Залезем внутрь. Базой для поиска с возвратом и недетминированных вычислений служит монада [], т. е. обычные списки. Элементы списка интерпретируются как возможные значения. Пример:

do a <- ['0'..'3'] b <- ['2'..'5'] guard (a == b) return [a,b]

имеет значение ["22", "33"] — эти варианты удовлетворяют условию. По сути, это то же list comprehension, для которого есть синтаксический (как и do) сахар. (Кстати, у GHC есть расширение, вводящее аналогичный синтаксис monad comprehension.)

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

import Control.Monad (guard) -- не забудьте, если будете копировать! data Man = Alfred | Bob | Clark | David | Englebert | Fox deriving (Eq, Enum, Bounded, Show) men :: [Man] men = [minBound..maxBound] fathers :: [(Man, Man)] fathers = [ (Alfred, Bob), (Alfred, Clark), (Bob, David), (Clark, Englebert), (Clark, Fox)] isFather :: Man -> Man -> Bool isFather a b = (a, b) `elem` fathers -- можно было бы написать: -- isFather Alfred Bob = True -- isFather Alfred Clark = True -- ... -- isFather _ _ = False -- но я ещё не выжил из ума :P isBrother :: Man -> Man -> Bool isBrother a b = a /= b && not (null [() | x <- men, isFather x a, isFather x b])

И смотрим:

я: [(x, y) | x <- men, y <- men, isBrother x y]

GHCi: [(Bob, Clark), (Clark, Bob), (Englebert, Fox), (Fox, Englebert)]

Вот оно как. Любители неупорядоченных-пар-где-не-надо могут добавить в deriving ещё и Ord, а в brothers соответственное x < y.)

Что скажут защитники семейства прологовых языков, я представляю. Sm_smile.svg Спасибо, не стоит — ведь и я не откажусь от своего сладкого заблуждения. ::

Пролог как бесперспективное заблуждение: 7 комментариев

  1. Логическое программирование за последние 20 лет весьма значительно развилось, просто учат везде только старому варианту Пролога. на самом деле многие проблемы давно решены.
    насчет типизации — есть Mercury.
    насчет зацикливания — частично решено в нем же, плюс еще есть CLP. есть и ASP в котором зацикливание невозможно в принципе.
    так-же найдены качественно новые недоступные в других языках вещи. Недоступные не потому что их нельзя реализовать а потому что их реализация вам только кажется простой. Ваш пример Пролога на Хаскеле весьма типичен. Да, простые задачи самописный движок осилит. но он ни за что не сравнится с нормальным компилятором пролога, который делали много лет, по эффективности. про задачи constraint programming и не говорю — там разницу в эффективности с тупым перебором видел и в 4000 раз.
    преимущество Пролога в том что он гораздо прозрачнее чем Хаскель. У Хаскеля слишком сложно все под капотом. у пролога есть своя ниша — инструментальное средство, язык инструментов программиста, язык решения задач, формулировок их, проектирования, написания прототипов. Хаскель не сможет вытеснить — программы на нем слишком непредсказуемы после модификаций. у Хаски вообще по-моему ниши нет, он чисто для написания диссертаций высосаных из пальца Sm_smile.svg без обид. по факту говорю. почти то-же самое с ООП — оно тоже предназначено чтоб написать кучу слов на те темы что уже решены Sm_smile.svg

    1. Здравствуйте! Только сейчас увидел ваши комментарии (кстати, я предупреждал об их тщёте, если что Sm_rolleyes.svg ).

      Как-нибудь почитаю об ASP, спасибо; заинтересовало, как там выкрутились.

      Насчёт «преимущество Пролога в том что он гораздо прозрачнее чем Хаскель. У Хаскеля слишком сложно все под капотом» — увы, с моей стороны хаскель прозрачнее пролога. Sm_smile.svg

  2. p.s. то что в Хаскеле ленивость по умолчанию это скорее плохо чем хорошо, поищите блог профессора Роберта Харпера, там все упомянуто — и то что ленивость не является необходимой для работы с бесконечными структурами данных и то что у нее есть свои проблемы которые обесценивают выгоду от нее.
    p.p.s. фактически ленивость приводит к тому что программа получается почти с такой же кучей неявных зависимостей внутри как и императивная. по факту без монад не обойтись. соответственно почти все бонусы от ФП теряются. и никакого автоматического распараллеливания тоже на самом деле не будет. что-то там конечно много лет пытаются реализовать но оно нормального ускорения не сможет дать никогда — потому что эмуляция ленивой семантики потребует кучу синхронизаций.

    1. Ну нет, не стоит смешивать ленивость с монадами. Насчёт зависимостей: можно, конечно, писать все функции с типами … -> IO a, но в этом нет нужды. Есть способы даже олисывать ввод-вывод так, чтобы можно было его большей частью потом автоматически протестировать.

      Насчёт лени: легко выключается в нужных местах, плюс GHC тоже не стоял на месте и оптимизировать может как (конкретнее не скажу, потому что, как ни неприятно сознавать, не читал на эту тему).

      Кстати, не буду здесь писать про сообщество, потому что про сообщества насчёт пролого-языков не знаю, но у Haskell всё с этим порядок.

  3. …кстати с параллелизмом в прологе все гораздо лучше чем в хаскеле. от задачи зависит конечно, но вполне часто встречается ситуация когда на кластере ускорение почти линейное (см система muse).
    … и еще раз прошу — на надо сравнивать впрямую Пролог с другими языками, вне его ниши. вы же не заставляете архитектора класть кирпичные стены? его задача рисовать чертежи. так и тут — пролог это исследовательский язык, инструмент решения задач. когда прототип оформился его переписывают на инженерном модульном языке на котором дальнейшая поддержка продукта будет проще. Mercury, ML… да хоть на Java. требования к таким языкам совсем другие, не те что к языкам прототипирования (хотя Меркури и МЛ довольно близки к исследовательским языкам — языкам для символьных вычислений и трансформаций сложных структур данных). на инженерных можно прототипировать, просто это черезчур сложно, много деталей — проще запутаться. каждому инструменту свое место.

    1. OK, я и не против, если он где-то действительно пригождается (и не потому, что альтернативы просто неизвестны или брошены), но вот «общего назначения» язык из него точно не выйдет. А из хаскеля, боюсь, выйдет… Если бы я не отвлекался на C# и не-программирование, поставил бы Haskell и Python в своих делах на поток, а пока в памяти слишком мало имён находится, чтобы легко с этим справляться.

      Насчёт написания программы на прологе, а потом переписывания в практических целях не могу ничего сказать. Кажется странным — при переписывании очень легко наплодить ошибок. Но в технологиях я не шарю. Разве что эксперименты мне видится одинаково пригодными делать на тех трёх упомянутых языках да ещё Wolfram Mathematica. И на тех при этом можно не только исследовать что-то, но и писать нормальные приложения.

  4. >Есть способы даже олисывать ввод-вывод

    про то и говорю что с этим проблемы. мелкие части можно, но при обьединении их в крупные уже теряется это.
    собственно я уже говорил в других местах в чем проблема Хаскеля. им восхищаются те кто лишь недавно начал им заниматься, их греет крутизна Sm_smile.svg по мере освоения народ начинает спотыкаться и обнаруживает что рекламные заявления (публикуемые такими-же начинающими хаскелистами в основном) не соответствуют действительности. дело не столько в том что хаскель необычен и потому не прост в освоении (что кстати сразу ставит крест на его перспективах именно в качестве языка общего назначения, он был и будет нишевым). дело в том что вся его необычность НЕ нужна.
    все его возможные ниши перекрываются МЛ и Прологом(Меркури?). а они гораздо проще и ПРЕДСКАЗУЕМЕЕ при командной разработке.
    хаскель — язык одиночек которые хотят выглядеть гениями. это проходит у них, с возрастом. лечится тренировкой прагматичности. Sm_smile.svg
    MIP, ASP, CLP — работают чаще с этим, потому что эти вещи дают больше при меньших усилиях и меньшем пафосе. да и поддерживать решения на них проще чем на Хаске.
    вот и выходит что нет и не будет у него ниши. так и будет несистематизированной академической забавой построенной без учета важных практических вещей. например, нормальной модульности нет. например, очень сложно предсказать потребление ресурсов у ленивой программы. смотрите подробности в блоге Харпера existentialtype на вордпрессе, там я даж часть переводил его статей год назад…
    понимаете, люди предпочитают говорить о достоинствах языков. а надо говорить о недостатках — об них спотыкается применение.

    все это имхо конечно.

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

:) :D :( :E: ;) :yes: :no: :donno: more »