Я потратил много времени на идею обоснованной индукции и подумал, что пришло время применить ее к простому случаю. Поэтому я хотел использовать его для определения факториальной функции и придумал:
Definition fac : nat -> nat := Fix LtWellFounded (fun _ => nat) (* 'LtWellFounded' is some proof *)
(fun (n:nat) =>
match n as n' return (forall (m:nat), m < n' -> nat) -> nat with
| 0 => fun _ => 1
| S m => fun (g : forall (k:nat), k < S m -> nat) => S m * g m (le_n (S m))
end).
, но тогда, конечно, сразу возникает вопрос о правильности. И, пытаясь доказать, что моя функция везде совпадала с обычной реализацией fac
, я понял, что все далеко не тривиально. На самом деле просто показать, что fac 0 = 1
:
Lemma fac0 : fac 0 = 1.
Proof.
unfold fac, Fix, Fix_F.
Show.
, кажется трудным. У меня осталась цель:
1 subgoal
============================
(fix Fix_F (x : nat) (a : Acc lt x) {struct a} : nat :=
match x as n' return ((forall m : nat, m < n' -> nat) -> nat) with
| 0 => fun _ : forall m : nat, m < 0 -> nat => 1
| S m =>
fun g : forall k : nat, k < S m -> nat => S m * g m (le_n (S m))
end (fun (y : nat) (h : y < x) => Fix_F y (Acc_inv a h))) 0
(LtWellFounded' 0) = 1
, и я не вижу, как ее уменьшить. Кто-нибудь может предложить путь вперед?