Функции должны быть завершены, поэтому вам придется использовать некоторый подтип вместо nat
или добавить аргумент, уменьшающий пространство ввода, например (H: a<>0)
Definition plusfive(a:nat) (H:a<>0) :=
match a as e return a=e -> _ with
| S _ => fun _ => a + 5
| _ => fun H0 => match (H H0) with end
end eq_refl.
Однако эти видыбыло обнаружено, что в больших разработках работать с трюками очень громоздко, и часто вместо этого используют полные функции базового типа, которые возвращают фиктивные значения для неверных входных значений, и доказывают, что функция вызывается с правильными аргументами отдельно от функции.определение.Посмотрите, например, как деление определяется в стандартной библиотеке.
Require Import Nat.
Print div.
div =
fun x y : nat => match y with
| 0 => y
| S y' => fst (divmod x y' 0 y')
end
: nat -> nat -> nat
Итак, Compute (div 1 0).
дает вам 0
.
Приятно то, что вы можете использовать div
в выраженияхнапрямую, без чередования доказательств того, что знаменатель ненулевой.Доказательство того, что выражение является правильным, затем выполняется после того, как оно было определено, а не одновременно.