169 похожих чатов

Извините за глупые вопросы, но как доказать, что функция, которая

вычисляет сумму всех элементов списка, работает корректно?
В наивном виде:
sumArray :: [Int] -> Int
sumArray [] = 0
sumArray (x:xs) = x + sumArray xs

Можно и так:
sumArray :: [Int] -> Int
sumArray lst = go lst 0
where
go [] acc = acc
go (x:xs) acc = go xs (x + acc)

13 ответов

21 просмотр

Индукцией

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

а не увидел вторую версию

кана
ну сначала определяешь что такое "сумма элементов ...

тогда надо доказать корректность кода через соответствие реализации определению

кана
не понял

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

@[simp] def sum₁ : List Nat → Nat | [] => 0 | x::xs => x + sum₁ xs @[simp] private def sum₂' (acc : Nat) : List Nat → Nat | [] => acc | x::xs => sum₂' (x + acc) xs def sum₂ : List Nat → Nat := sum₂' 0 private theorem sum₂'_correct : sum₂' acc xs = sum₁ xs + acc := by induction xs generalizing acc with | nil => simp | cons x xs ih => simp [Nat.add_assoc, Nat.add_left_comm, ih] theorem sum₂_correct : sum₂ = sum₁ := by funext xs; apply sum₂'_correct

ㅤ-Атеист Автор вопроса
кана
@[simp] def sum₁ : List Nat → Nat | [] => 0 | x::x...

А, прикольно! Спасибо! ❤️ (почему в хаскель-чате нет реакции "❤️"? неужели хаскелисты такие бессердечные??) Базовый случай: []. 0 = 0 Допустим, что sum₂' acc xss = sum₁ xss + acc и xss = x:xs Тогда если справедливо sum₂' acc1 xs = sum₁ xs + acc1, то утверждение верно. Тогда по определению: sum₂' (x + acc) xs = x + sum₁ xs + acc Вследствие ассоциативности сложения получаем: sum₂' (x + acc) xs = sum₁ xs + (x + acc) ч.т.д. Ну и для доказательства sum₂ xs = sum₁ xs: sum₂' 0 xs = sum₁ xs + 0 (a + 0 = a) По предыдущей теореме данное утверждение верно, а значит и верно исходное утверждение

ㅤ Атеист
А, прикольно! Спасибо! ❤️ (почему в хаскель-чате н...

есть еще вот такой способ в lean4 это раписать для читаемости private theorem sum₂'_correct : sum₂' acc xs = sum₁ xs + acc := by induction xs generalizing acc with | nil => simp | cons x xs ih => calc sum₂' acc (x :: xs) = sum₂' (x + acc) xs := by rfl _ = sum₁ xs + (x + acc) := by apply ih _ = x + sum₁ xs + acc := by simp [Nat.add_assoc, Nat.add_left_comm] _ = sum₁ (x :: xs) + acc := by rfl

кана
есть еще вот такой способ в lean4 это раписать для...

вообще вот эта задача + задача на reverse скажем это такая классическая задача на доказательства, которая обучает, что не всегда стоит индукцию применять бездумно, нужно сначала подумать а для чего именно индуцировать, а так же думать, с каким мативом индуцировать. В книжках обычно одна из этих двух задач есть вот тут скажем два момента важных это: 1. индуцировать нужно для sum₂' а не для sum₂ 2. индукция должна быть обобщена по acc, потому что с каждым шагом функции acc меняется вот есть статьейка еще с подобными задачами https://jamesrwilcox.com/InductionExercises.html

ㅤ-Атеист Автор вопроса
кана
вообще вот эта задача + задача на reverse скажем э...

Я взял эту задачу из CLRS (4-я редакция! цвета появились!)

ㅤ-Атеист Автор вопроса
кана
вообще вот эта задача + задача на reverse скажем э...

Касательно reverse list неплохо было бы узнать μ(reverse)

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
у вас два процесса. один посылает другому сигнал. у вас есть код обоих процессов? если всё не так - расскажите как оно на самом деле. а именно кто кому чего, есть-ли консоли,...
Karagy
6
Карта сайта