Что такое лямбда нулевое

Обновлено: 05.07.2024

Я начинающий диагност, помогите пожалуйста советом.
Сегодня сканматиком диагностировал Cherry Tiggo. У нее вторая лямбда всегда показывает постоянный сигнал, примерно 0,46 вольт, а сигнал с первой меняется, как положено.
Я попробовал переставить лямбды местами (они одинаковые), картина не изменилась.
Прозвонил разъемы, на обоих одинаковые показания.
В чем дело? Может ли это быть из-за самого катализатора?
чек не горит, но машина, как-то тупо реагирует на газ. В ошибках было "пропуски в воспламенении".

Hudlam

данила

Второй зонд стоит после катализатора. Там состав выхлопа практически не меняется из-за инерционности катализатора.

Is_18

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

motor

Спасибо,
А я еще посмотрел ее показания на форде фокусе 2006 г. и лансере 2005. На них вторая лямбда показывает плавающее напряжение. Это что, значит катализаторам хана?
И еще, в сканматике есть такая вкладка "Тесты", в ней не проходит тест катализатор, пишет "не завершено". И выделено красным параметр "время переключения между датчиками". Минимум должен быть 0,012 сек, а показывает 0.000.
Это что означает?

Спасибо,
А я еще посмотрел ее показания на форде фокусе 2006 г. и лансере 2005. На них вторая лямбда показывает плавающее напряжение. Это что, значит катализаторам хана?
И еще, в сканматике есть такая вкладка "Тесты", в ней не проходит тест катализатор, пишет "не завершено". И выделено красным параметр "время переключения между датчиками". Минимум должен быть 0,012 сек, а показывает 0.000.
Это что означает?

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

В большинстве примеров, которые я видел, это скорее стилистический или структурный выбор. И вроде бы ломает "Правильный способ сделать что-то" только в правиле python. Как это делает мои программы, правильнее, надежнее, быстрее или проще понять? (Большинство стандартов кодирования, которые я видел, как правило, говорят вам избегать слишком сложных операторов в одной строке. Если это облегчает чтение, разбейте его.)

ОТВЕТЫ

Ответ 1

Вот хороший пример:

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

Ответ 2

Синтаксис более краткий в некоторых ситуациях, в основном при работе с map и др.

мне кажется лучше, чем:

Я думаю, что лямбда - лучший выбор в этой ситуации, потому что def double кажется почти отключенным от map , который его использует. Кроме того, я предполагаю, что это имеет дополнительное преимущество, которое функция отбрасывается, когда вы закончите.

Существует один недостаток лямбда, который ограничивает его полезность в Python, на мой взгляд: lambdas может иметь только одно выражение (т.е. вы не можете иметь несколько строк). Он просто не может работать на языке, который создает пробелы.

Плюс, всякий раз, когда я использую лямбда, я чувствую себя потрясающе.

Ответ 3

Лямбда-функции наиболее полезны в таких вещах, как функции обратного вызова или места, в которых вам нужна функция throwaway. Пример JAB - это лучше - он будет лучше сопровождаться аргументом ключевого слова key , но он по-прежнему предоставляет полезную информацию.

появляется на расстоянии 300 строк от

что делает ключ? На самом деле нет никаких указаний. У вас может быть какая-то догадка, особенно если вы знакомы с этой функцией, но обычно это требует возврата. Ото,

говорит вам намного больше.

  • Сортировка принимает функцию как аргумент
  • Эта функция принимает 1 параметр (и "возвращает" результат)
  • Я пытаюсь отсортировать этот список по 2-ому значению каждого из элементов списка
  • (Если список был переменной, поэтому вы не могли видеть значения), эта логика ожидает, что в списке будет как минимум 2 элемента.

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

Плюс это не загрязняет ваше пространство имен;)

Ответ 4

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

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

Ответ 5

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

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

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

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

Но это все еще структурный выбор. Вы можете сделать это иначе. Но то же самое касается объектно-ориентированного программирования;)

Ответ 6

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

явно упоминает четыре анонимных количества: -1, 0, 10 и результат лямбда-оператора плюс подразумеваемый результат вызова map . возможно создание значений анонимных типов на некоторых языках. поэтому игнорируйте поверхностную разницу между функциями и числами. вопрос о том, когда использовать анонимную функцию в отличие от именованной, аналогичен вопросу о том, когда нужно поставить в коде голый номер буква и когда объявить TIMES_I_WISHED_I_HAD_A_PONY или BUFFER_SIZE заранее. бывают случаи, когда необходимо использовать литерал (числовой, строковый или функциональный), и бывают случаи, когда более целесообразно называть такую ​​вещь и ссылаться на нее через ее имя.

см., например. Allen Holub провокационная, задумчивая или вызывающая гнев книга о шаблонах проектирования на Java; он довольно мало использует анонимные классы.

Ответ 7

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

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

Также часто полезно использовать при сортировке как ключ:

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

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

Ответ 8

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

"Один из ключевых соображений Guido - это то, что код читается гораздо чаще, чем он написан".

Ответ 9

Lambdas - это объекты, а не методы, и они не могут быть вызваны таким же образом, как и методы. например,

succ mow содержит объект Proc, который мы можем использовать как любой другой:

дает нам выход = 3

Ответ 10

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

В последнем случае написать отдельную полноценную функцию только для возврата -cmp(a, b) создаст больше недоразумений, чем лямбда.

Ответ 11

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

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

Ответ 12

Другое дело, что у python нет операторов switch. Объединение лямбда с диктонами может быть эффективной альтернативой. например:.

Ответ 13

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

Ответ 14

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

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

Ответ 15

Lambdas позволяет вам создавать функции "на лету". Большинство примеров, которые я видел, не намного больше, чем создание функции с параметрами, переданными во время создания, а не с выполнением. Или они упрощают код, не требуя официального объявления функции перед использованием.

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

Машина, сейчас, кушает по трассе 15 литров. Решил проверить мультиметром лямбда зонд. + к ней, - на клему аккума. Так вот на мультиметре (режим 20 вольт) показывает 0,00 вольт, но с определеным игтервало, чуть больше секунды, слева от нулей моргает значок -. КЗ, замена провода до компа? Или всё норм. При увеличении и уменьшении оборотов, реакция та же.

Нихера не понял но у циркониевого ЛЗ опорное напряжение 0,45в (дсв не заведен). При работающем двс, прогретом катализаторе (15 минут проезда) напряжение от 0,1 до 0,9в (типа синуса). Проверяют на оборотах 2000-2500, по моему, если память не изменяет, должно быть не менее 8 переключений за 10 сек.

Цифровым тестером это не увидеть, нужен стрелочник или осцилл.

Есшо, возможно лз может быть жив но неисправности в выпускном коллекторе, могут обманывать ЛЗ и ЛЗ будет давать неверный сигнал. Если ЛЗ очень стар (100000 км) то ЛЗ надо заменить.

Нихера не понял но у циркониевого ЛЗ опорное напряжение 0,45в (дсв не заведен). При работающем двс, прогретом катализаторе (15 минут проезда) напряжение от 0,1 до 0,9в (типа синуса). Проверяют на оборотах 2000-2500, по моему, если память не изменяет, должно быть не менее 8 переключений за 10 сек.

Цифровым тестером это не увидеть, нужен стрелочник или осцилл.

Есшо, возможно лз может быть жив но неисправности в выпускном коллекторе, могут обманывать ЛЗ и ЛЗ будет давать неверный сигнал. Если ЛЗ очень стар (100000 км) то ЛЗ надо заменить.

Опорное напряжение 0 вольт, при прогретом двигателе, 0 вольт. Только минус моргает.И хотя бы что-то, да цифровой мультиметр увидеть должен. Вопрос вот, если отключу клему ЛЗ от сети и накину + провод на неё а - на клему, напряжение должно быть? Напряжение идет от ЛЗ к компу или наоборот?

Отключил ЛЗ от компа, на холодный двс на ЛЗ 0 вольт, от компа идет 0, 07. После прогрева авто результаты те же.

Моски не колупайте, можно например так проверить циркониевый кислородник

Моски не колупайте, можно например так проверить циркониевый кислородник

Точно. Выкрутил и на руках мерил напряжение. по 0. Пошел купил новый, положл рядом и замерил. 0,3 вольта. Мертвая лямбда) Ксатти, когда провод от неё откинул и поехал за новой, машина превратилась в гоночный балит, никогда так не насилась))_))

Точно. Выкрутил и на руках мерил напряжение. по 0. Пошел купил новый, положл рядом и замерил. 0,3 вольта. Мертвая лямбда) Ксатти, когда провод от неё откинул и поехал за новой, машина превратилась в гоночный балит, никогда так не насилась))_))

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

Машина, сейчас, кушает по трассе 15 литров. Решил проверить мультиметром лямбда зонд. + к ней, - на клему аккума. Так вот на мультиметре (режим 20 вольт) показывает 0,00 вольт, но с определеным игтервало, чуть больше секунды, слева от нулей моргает значок -. КЗ, замена провода до компа? Или всё норм. При увеличении и уменьшении оборотов, реакция та же.

Точно такая же проблема и у меня, напряжение на контакте лямбды практически по нулям показывает 0.0334 В. Мультиметр очень точный:)
Замер делал во всех режимах: на холодную, на горячую, при резком поднятии оборотов и с удержанием и без.. короче всегда одно и то же. Варьируется в пределах от 0.03 В до 0.035 В.
Расход дикий тоже: трасса около 15 литров, город 19 литров.
Мучает вопрос теперь, менять комп или лямду.

А может на 5а двигателе вообще нет ни какого напряжения на лямде, типа начинает выдавать сама лямда в работе?

Лямбда-исчисление (англ. lambda calculus) — формальная система, придуманная в 1930-х годах Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией. Эта концепция показала себя удобной и сейчас активно используется во многих языках программирования.

Содержание

[math] \Lambda \to V\\ \Lambda \to \Lambda \ \Lambda\\ \Lambda \to \lambda V . \Lambda [/math]

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

В первом случае функция является просто переменной. Во втором происходит аппликация (применение) одной функции к другой. Это аналогично вычислению функции-левого операнда на аргументе-правом операнде. В третьем — абстракция по переменной. В данном случае происходит создание функции одного аргумента с заданными именем аргумента и телом функции.

Рассмотрим, например, [math]\lambda[/math] -терм [math]\operatorname = \lambda x\ .\ x[/math] . Эта функция принимает аргумент и возвращает его неизменённым. Например, [math]\operatorname\ 2 \equiv 2[/math] . Аналогично, [math]\operatorname\ y \equiv y[/math] .

[math] x\\ (x\ z)\\ (\lambda x.(x\ z))\\ (\lambda z.(\lambda w.((\lambda y.((\lambda x.(x\ z))\ y))\ w)))\\ [/math]

Иногда [math]\lambda[/math] -термы пишут по другому. Для краткости подряд идущие лямбды заменяют на одну. Например:

[math]\lambda x\ .\ \lambda y\ .P\ \to\ \lambda xy.P[/math]

  • Аппликация: [math]x\ y\ z\ w \equiv ((x\ y)\ z)\ w[/math]
  • Абстракция забирает себе всё, до чего дотянется: [math]\lambda x\ .\ \lambda y\ .\ \lambda z\ .\ z\ y\ x \equiv \lambda x\ .\ (\lambda y\ .\ (\lambda z\ .\ ((z\ y)\ x)))[/math]
  • Скобки играют привычную роль группировки действий

Связанными переменными называются все переменные, по которым выше в дереве разбора были абстракции. Все остальные переменные называются свободными.

Например, в [math]\lambda x\ .\ y\ x[/math] , [math]x[/math] и связана, а [math]y[/math] — свободна. А в [math]\lambda y\ .\ x\ (\lambda x\ .\ x)[/math] в своём первом вхождении переменная [math]x[/math] свободна, а во втором — связана.

Связанные переменные — это аргументы функции. То есть для функции они являются локальными.

Рассмотрим функции [math]\lambda y\ .\ y[/math] и [math]\lambda x\ .\ y[/math] . В первой из них при взгляде на [math]y[/math] понятно, что она имеет отношение к переменной, по которой производилась абстракция. Если по одной и той же переменной абстракция производилась более одного раза, то переменная связана с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в [math]\lambda x\ .\ \lambda x\ .\ \lambda y\ .\ \lambda x\ .\ x[/math] , переменная [math]x[/math] связана с самой правой абстракцией по [math]x[/math] .

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


Функции [math]\lambda x\ .\ \lambda y\ .\ x\ y\ z[/math] и [math]\lambda a\ .\ \lambda x\ .\ a\ x\ z[/math] являются [math]\alpha[/math] -эквивалентными, а [math]\lambda x\ .\ \lambda y\ .\ y\ z[/math] и [math]\lambda y\ .\ \lambda x\ .\ y\ z[/math] — нет.

и замкнуто относительно следующих правил


В [math]\beta[/math] -редукции вполне возможна функция вида [math]\lambda x. \lambda x.x[/math] . Во время подстановки вместо [math]x[/math] внутренняя переменная не заменяется - действует принцип локальной переменной. Но принято считать, что таких ситуаций не возникает и все переменные называются разными именами.

Существует также альтернативное эквивалентное определение [math]\lambda[/math] -исчисления. В оригинальном определении для обозначения переменных использовались имена, и была проблема с тем, что не были запрещены одинаковые имена в разных абстракциях.

От этой проблемы можно избавиться следующим образом. Вместо имени переменной будет храниться натуральное число — количество абстракций в дереве разбора, на которое нужно подняться, чтобы найти ту лямбду, с которой данная переменная связана. В данной нотации получаются несколько более простые определения свободных переменных и [math]\beta[/math] -редукции.

Грамматику нотации можно задать как:

[math]e\ ::= n\ |\ \lambda .e\ |\ e\ e[/math]

Примеры выражений в этой нотации:

Standart de Bruijn
$\lambda x.x$ $\lambda .0$
$\lambda z.z$ $\lambda .0$
$\lambda x. \lambda y.x$ $\lambda . \lambda .1$
$\lambda x. \lambda y. \lambda s. \lambda z.x\ s\ (y\ s\ z)$ $\lambda . \lambda . \lambda . \lambda .3\ 1(2\ 1\ 0)$
$(\lambda x.x\ x)(\lambda x.x\ x)$ $(\lambda .0\ 0)(\lambda .0\ 0)$
$(\lambda x. \lambda x.x)(\lambda y.y)$ $(\lambda .\lambda .0)(\lambda .0)$

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

Введём на основе лямбда-исчисления аналог натуральных чисел, основанный на идее, что натуральное число — это или ноль, или увеличенное на единицу натуральное число.

[math]\bar 0 = \lambda s\ .\ \lambda z\ .\ z[/math] [math]\bar 1 = \lambda s\ .\ \lambda z\ .\ s\ z[/math] [math]\bar 2 = \lambda s\ .\ \lambda z\ .\ s\ (s\ z)[/math] [math]\bar 3 = \lambda s\ .\ \lambda z\ .\ s\ (s\ (s\ z))[/math]

Каждое число будет функцией двух аргументов: какой-то функции и начального значения. Число [math]n[/math] будет [math]n[/math] раз применять функцию к начальному значению и возвращать результат. Если такому "числу" дать на вход функцию [math](+1)[/math] и [math]0[/math] в качестве начального значения, то на выходе как раз будет ожидаемое от функции число: [math]\bar 3\ (+1)\ 0 \equiv 3[/math] .

Функция, прибавляющая [math]1[/math] к числу, должна принимать первым аргументом число. Но число — функция двух аргументов. Значит, эта функция должна принимать три аргумента: "число" [math]n[/math] , которое хочется увеличить, функция, которую надо будет [math]n+1[/math] раз применить, и начальное значение.

[math]\operatorname = \lambda n\ .\ \lambda s\ .\ \lambda z\ .\ s\ (n\ s\ z)[/math]

Здесь [math]n\ s\ z[/math] — [math]n[/math] раз применённая к [math]z[/math] функция [math]s[/math] . Но нужно применить [math]n+1[/math] раз. Отсюда [math]s\ (n\ s\ z)[/math] .

Сложение двух чисел похоже на прибавление единицы. Но только надо прибавить не единицу, а второе число.

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ s\ (m\ s\ z)[/math]

[math]n[/math] раз применить [math]s[/math] к применённому [math]m[/math] раз [math]s[/math] к [math]z[/math]

[math](\operatorname\ \bar 3\ \bar 3)\ (+1)\ 0 \equiv 6[/math]

[math](\operatorname\ ((\operatorname\ 2\ 5)(+1)\ 0)\ 4)(+1)0 \equiv 11[/math]

Умножение похоже на сложение, но прибавлять надо не единицу, а второе число. Или, в терминах нумералов Чёрча, в качестве применяемой несколько раз функции должна быть не [math]s[/math] , а функция, применяющая [math]n[/math] раз [math]s[/math] .

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ (m\ s)\ z[/math]

Здесь [math]m\ s[/math] — функция, которая [math]m[/math] раз применит [math]s[/math] к тому, что дадут ей на вход. С помощью [math]\eta[/math] -редукции можно немного сократить эту формулу

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ n\ (m\ s)[/math]

[math](\operatorname \bar 3\ \bar 3)\ (+1)\ 0 \equiv 9[/math]

It's a kind of magic

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ m\ n\ s\ z[/math]

[math](\operatorname\ \bar 3\ (\operatorname\ \bar 3))\ (+1)\ 0 \equiv 81[/math]

[math]\operatorname = \lambda a\ .\ \lambda b\ .\ a[/math]

[math]\operatorname = \lambda a\ .\ \lambda b\ .\ b[/math]

Функции двух аргументов, возвращающие первый и второй, соответственное, аргументы. Забавный факт: [math]\operatorname \equiv_\alpha \operatorname[/math] . Эти функции сделаны такими для того, чтобы красиво написать функцию [math]\operatorname[/math] :

[math]\operatorname = \lambda p\ .\ \lambda t\ .\ \lambda e\ .\ p\ t\ e[/math]

Если ей в качестве первого аргумента дадут [math]\operatorname[/math] , то вернётся [math]t[/math] , иначе — [math]e[/math] .

Стандартные функции булевой логики:

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \operatorname\ n\ m\ \operatorname[/math]

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \operatorname\ n\ \operatorname \ m[/math]

[math]\operatorname = \lambda b\ .\ \operatorname\ b\ \operatorname \ \operatorname[/math]

Ещё одной важной функцией является функция проверки, является ли число нулём:

[math]\operatorname = \lambda n\ .\ n\ (\lambda c\ .\ \operatorname)\ \operatorname[/math]

Функция выглядит несколько странно. [math]\lambda c \to \operatorname[/math] - функция, которая независимо от того, что ей дали на вход, возвращает [math]\operatorname[/math] . Тогда, если в качестве [math]n[/math] будет дан ноль, то функция, по определению нуля, не выполнится ни разу, и будет возвращено значение по умолчанию [math]\operatorname[/math] . Иначе же функция будет запущено, и вернётся [math]\operatorname[/math] .

[math]\operatorname = \lambda a\ .\ \lambda b\ .\ \lambda t\ .\ t\ a\ b[/math]

[math]\operatorname = \lambda p\ .\ p\ \operatorname[/math]

[math]\operatorname = \lambda p\ .\ p\ \operatorname[/math]

Функция [math]\operatorname[/math] принимает два значения и запаковывает их в пару так, чтобы к ним можно было обращаться по [math]\operatorname[/math] и [math]\operatorname[/math] . В [math]\operatorname[/math] и [math]\operatorname[/math] вместо [math]t[/math] в [math]\operatorname[/math] будет подставлено [math]\operatorname[/math] или [math]\operatorname[/math] , возвращающие, соответственно, первый и второй аргументы, то есть [math]a[/math] или [math]b[/math] , соответственно.

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

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ m\ \operatorname n[/math]

Это то же самое, что [math]m[/math] раз вычесть единицу из [math]n[/math] .

Осталось, собственно, функция для вычитания единицы. Однако, это не так просто, как может показаться на первый взгляд. Проблема в том, что, имея функцию, которую нужно применить для того, чтобы продвинуться вперёд, продвинуться назад будет проблематично. Если попробовать воспользоваться идеей о том, чтобы, начав от нуля, идти вперёд, и пройти на один шаг меньше, то будет не очень понятно, как же остановиться ровно за один шаг до конца. Для реализации вычитания единицы сделаем следующее. [math]n[/math] раз выполним следующее: имея пару [math]\langle n-1, n-2\rangle[/math] построим пару [math]\langle n, n-1\rangle[/math] . Тогда после [math]n[/math] шагов во втором элементе пары будет записано число [math]n-1[/math] , которое и хочется получить.

[math]\operatorname = \lambda n\ .\ \lambda s\ .\ \lambda z.\ \operatorname\ ( n\ ( \lambda p\ .\ \operatorname\ (s\ (\operatorname p))\ (\operatorname p) )\ (\operatorname\ z\ z))[/math]

Если вы ничего не поняли, не огорчайтесь. Вычитание придумал Клини, когда ему вырывали зуб мудрости. А сейчас наркоз уже не тот.

Так как вычитание определено таким способом, чтобы для случая, в котором уменьшаемое больше, чем вычитаемое, возвращать ноль, можно определить сравнение на больше-меньше через него. Равными же числа [math]a[/math] и [math]b[/math] считаются, если [math]a - b = 0 \wedge b - a = 0[/math] .

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ n\ m)[/math]

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \operatorname\ n\ (\operatorname m)[/math]

[math]\operatorname = \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ (\operatorname\ n\ m))\ (\operatorname\ (\operatorname\ m\ n))[/math]

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

[math]\operatorname = \lambda x\ .\ \operatorname\ (\operatorname\ x)\ \bar 1\ (\operatorname\ (\operatorname\ x))[/math]

Мы столкнулись с проблемой. В определении функции [math]\operatorname[/math] используется функция [math]\operatorname[/math] . При формальной замене, получим бесконечную функцию. Можно попытаться решить эту проблему следующим образом

[math]\operatorname = (\lambda f\ .\ \lambda x\ .\ \operatorname\ (\operatorname\ x)\ \bar 1\ (f\ (\operatorname\ x)))\ \operatorname[/math]


Лямбда исчисление обладаем замечательным свойством: у каждой функции есть неподвижная точка!

Рассмотрим следующую функцию.

[math]\operatorname = \lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x))[/math]

Заметим, что [math]\operatorname \to_\beta^* \lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))[/math] . Или, что то же самое, [math]\lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)) \to_\beta^*[/math] [math]\lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))[/math]

[math]\operatorname = \lambda f\ .\ \lambda x\ .\ \operatorname\ (\operatorname\ x)\ \bar 1\ (\operatorname\ x\ (f\ (\operatorname\ x)))[/math]

Как было показано выше, [math]\operatorname f \to_\beta^* f\ (\operatorname f)[/math] , то есть, [math]\operatorname\ \operatorname \to_\beta^* \operatorname[/math] , где [math]\operatorname[/math] — искомая функция, считающая факториал.

[math]\operatorname = \operatorname\ \operatorname[/math]

Это даст функцию, которая посчитает факториал числа. Но делать она это будет мееедленно-меееедленно. Для того, чтобы посчитать [math]5![/math] потребовалось сделать 66066 [math]\beta[/math] -редукций.

Наиболее известным комбинатором неподвижной точки является [math]Y[/math] -комбинатор, введенный известным американским ученым Хаскеллом Карри как

[math]Y\ = \ \lambda f.(\lambda x.f(x\ x))\ (\lambda x.f(x\ x))[/math]

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

[math]\operatorname = \lambda div\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ n\ m)\ \bar 0\ (\operatorname\ (div\ (\operatorname\ n\ m)\ m))[/math]

[math]\operatorname = \operatorname\ \operatorname[/math]

И остатка от деления

[math]\operatorname = \lambda mod\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ n\ m)\ n\ (mod\ (\operatorname\ n\ m)\ m)[/math]

[math]\operatorname = \operatorname\ \operatorname[/math]

[math]\operatorname[/math] — принимает число, которое требуется проверить на простоту и то, на что его надо опытаться поделить, перебирая это от [math]2[/math] до [math]p-1[/math] . Если на что-нибудь разделилось, то число — составное, иначе — простое.

[math]\operatorname =[/math] [math]\lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname\ (\operatorname\ p\ i)\ \operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ p\ i))\ \operatorname\ (f\ p\ (\operatorname\ i)))[/math]

[math]\operatorname = \operatorname\ \operatorname[/math]

[math]\operatorname = \lambda p\ .\ \operatorname\ p\ \bar 2[/math]

Следующее простое число. [math]\operatorname[/math] — следующее, больше либо равное заданного, [math]\operatorname[/math] — следующее, большее заданного.

[math]\operatorname = \lambda f\ .\ \lambda p\ .\ \operatorname\ (\operatorname\ p)\ p\ (f\ (\operatorname\ p)) [/math]

[math]\operatorname = \operatorname\ \operatorname[/math]

[math]\operatorname = \lambda p\ .\ \operatorname\ (\operatorname\ p)[/math]

[math]\operatorname[/math] пропрыгает [math]i[/math] простых чисел вперёд. [math]\operatorname[/math] принимает число [math]i[/math] и пропрыгивает столько простых чисел вперёд, начиная с двойки.

[math]\operatorname = \lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname\ (\operatorname\ i)\ p\ (f\ (\operatorname\ p)\ (\operatorname\ i))[/math]

[math]\operatorname = \lambda i\ .\ \operatorname\ \bar 2\ i[/math]

. и всего через 314007 [math]\beta[/math] -редукций вы узнаете, что третье простое число — семь!

Для работы со списками чисел нам понадобятся следующие функции:

  • [math]\operatorname[/math] — возвращает пустой список
  • [math]\operatorname[/math] — принимает первый элемент и оставшийся список, склеивает их
  • [math]\operatorname[/math] — вернуть голову списка
  • [math]\operatorname[/math] — вернуть хвост списка

[math]\operatorname = \operatorname\ \operatorname\ \bar 1[/math]

[math]\operatorname = \lambda h\ .\ \lambda t\ .\ \operatorname\ (\operatorname\ (\operatorname\ t))\ (\operatorname\ (\operatorname\ t)\ (\operatorname\ (\operatorname\ (\operatorname\ t))\ h))[/math]

[math]\operatorname = \lambda list\ .\ \operatorname\ (\operatorname\ list)\ (\operatorname\ (\operatorname\ (\operatorname\ list)))[/math]

[math]\operatorname = \lambda list\ .\ \operatorname\ (\operatorname\ (\operatorname\ list)) (\operatorname\ (\operatorname\ list)\ (\operatorname\ (\operatorname\ (\operatorname\ list))))[/math]

[math]\operatorname =[/math] [math] \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ (\operatorname\ n\ m))\ (f\ (\operatorname\ n\ m)\ m)\ n[/math]

[math]\operatorname =[/math] [math] \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname\ (\operatorname\ (\operatorname\ n\ m))\ (\operatorname\ (f\ (\operatorname\ n\ m)\ m))\ \bar 0[/math]

[math]\operatorname = \operatorname\ \operatorname[/math]

Читайте также: