I'm trying to formalize each integer as an equivalence class of pairs of natural numbers, where the first component is the positive part, and the second component is the negative part.
Definition integer : Type := prod nat nat.
I want to define a normalization function where positives and negatives cancel as much as possible.
Fixpoint normalize (i : integer) : integer :=
let (a, b) := i in
match a with
| 0 => (0, b)
| S a' => match b with
| 0 => (S a', 0)
| S b' => normalize (a', b')
end
end.
However Coq says:
Error: Recursive definition of normalize is ill-formed. In environment normalize : integer -> integer i : integer a : nat b : nat a' : nat b' : nat Recursive call to normalize has principal argument equal to "(a', b')" instead of a subterm of "i".
I think this might have to do with well-founded recursion?
(a, b)
is not a subterm of(S a, S b)
. I would create a helper function which accepts two arguments (a
andb
). This waya
is a subterm ofS a
and the function'll eventually converge. Maybe you can somehow make coq understand that your initial function converges, but I don't know coq enough to say whether it's possible. You may try{measure (fst i)}
, but I can't check it right now. – user2956272Program Fixpoint normalize (i: int) { measure (fst i) } : integer
may work. See an example here: cs.cornell.edu/courses/cs6115/2017fa/notes/lecture7.html (withmeasure (length xs)
) – user2956272