До express, что заданный список натуральных чисел находится в порядке убывания, вы можете использовать существующие функции в модуле List
Coq.
Require Import List Lia.
Definition desc (l : list nat) : Prop :=
forall i j, i <= j -> nth j l 0 <= nth i l 0.
Что я сделал? Я только что выразил, что значение в ранге i
должно быть больше, чем значение в ранге j
для любого j
больше, чем i
. Это умно в тонком смысле. Выражение nth j l 0
фактически представляет значение в ранге i
в l
, если i
меньше длины списка или 0
в противном случае . Бывает, что 0
меньше любого другого натурального числа, поэтому это определение работает. Если бы вместо этого вы запросили список чисел в строго в порядке убывания , то мне пришлось бы написать более точное определение, включающее только ранги, которые меньше длины списка (вы можете использовать функцию length
за это). Я позволю вам сделать это в качестве упражнения.
Когда вы пишете логический предикат, такой как desc
, важно проверить это определение, чтобы убедиться, что вы действительно захватили понятие ты имел в виду. Чтобы проверить мое собственное определение, я написал следующий код:
Definition sample1 := 1 :: 2 :: 3 :: nil.
Definition sample2 := map (fun x => 10 - x) sample1.
Lemma s2_desc : desc sample2.
Proof.
intros [ | [ | [ | [ | ]]]] [ | [ | [ | [ | ]]]];
intros ilej; simpl; lia.
Qed.
Lemma s1_n_desc : ~desc sample1.
Proof.
intros abs; generalize (abs 0 1 (le_S _ _ (le_n _))).
compute; lia.
Qed.
Доказательство s2_desc
является доказательством грубой силы, оно фактически проверяет все пары рангов, меньших 4, и проверяет это во всех в этих случаях сравнения между натуральными числами (рангами или значениями в списке) дают логически доказуемые формулы.
Доказательство s1_n_desc
используется для проверки того, что мое определение desc
действительно отвергает список, который явно не удовлетворяет критерию. Хорошо, что я написал это доказательство, потому что оно помогло мне обнаружить ошибку в моем коде desc
, которая не была обнаружена предыдущим доказательством: я написал nth 0 l i
вместо nth i l 0
!
Последнее, но не менее важное, мое решение начинается с Require Import List Lia.
Это означает, что мы используем два существующих модуля Coq. Первый предоставляет часто используемые функции для списков, второй предоставляет автоматизированный инструмент c для выполнения простых доказательств сравнения чисел (фактически, натуральных чисел или целых чисел).
В качестве следующего шага можно также напишите логическую функцию, которая точно вычисляет значение true
, когда ее ввод находится в порядке убывания, и разработайте доказательства тестов для проверки того, что обе функции ведут себя соответственно.