Другое решение заключается в использовании вложенной точки фиксации.
Fixpoint evalT (t:T) {struct t} : nat :=
match t with
| foo => 1
| bar n x => let fix evalBar n {struct n} :=
match n with
| 0 => 0
| S n' => Nat.add (evalT x) (evalBar n')
end
in evalBar n
end.
Важным моментом является удаление аргумента x
из evalBar
.Таким образом, рекурсивный вызов evalT
выполняется для x
из bar n x
, а не x
, заданного в качестве аргумента для evalBar
, и, таким образом, средство проверки завершения может проверить определение evalT
.
Это та же идея, которая заставляет работать версию с nat_rec
, предложенную в другом ответе.