Предположим, у нас есть список:Как вы подтверждаете завершение рекурсивной длины списка?
List = nil | Cons(car cdr:List).
Обратите внимание, что я говорю о модифицируемых списках! И тривиальная рекурсивная функция длины:
recursive Length(List l) = match l with
| nil => 0
| Cons(car cdr) => 1 + Length cdr
end.
Естественно, это заканчивается только тогда, когда список не является круговым:
inductive NonCircular(List l) = {
empty: NonCircular(nil) |
\forall head, tail: NonCircular(tail) => NonCircular (Cons(head tail))
}
Обрати внимание, что этот предикат, реализуются в виде рекурсивной функции, также не завершаться в круговом списке.
Обычно я вижу доказательства окончания обхода списка, которые используют длину списка как ограниченный коэффициент убывания. Они полагают, что Length
неотрицателен. Но, как я вижу, этот факт (Length l >= 0
) следует из окончания Length
на первом месте.
Как вы доказываете, что Length
заканчивается и неотрицателен на NonCircular
(или эквивалентном, лучше определенном предикате) списков?
Я пропустил здесь важную концепцию?
Я согласен, за исключением последнего абзаца. Прекращение имеет важное значение для доказательственных программ. в противном случае это доказательство для false: 'f: true -> false: = {return f();}' – Necto