I'm trying to translate the argument I gave in this answer into Isabelle and I managed to prove it almost completely. However, I still need to prove:
"(∑k | k ∈ {1..n} ∧ d dvd k. f (k/n)) =
(∑q | q ∈ {1..n/d}. f (q/(n/d)))" for d :: nat
My idea was to use this theorem:
sum.reindex_bij_witness
however, I cannot instantiate the transformations i,j that relate the sets S,T of the theorem. In principle, the setting should be:
S = {k. k ∈ {1..n} ∧ d dvd k}
T = {q. q ∈ {1..n/d}}
i k = k/d
j q = q d
I believe there is a typing error. Perhaps I should be using div?
First of all, note that instead of gcd a b = 1
, you should write coprime a b
. That is equivalent (at least for all types that have a GCD), but it is more convenient to use.
Second, I would not write assumptions like ⋀n. F n = …
. It makes more sense to write that as a defines
, i.e.
lemma
fixes F :: "nat ⇒ complex"
defines "F ≡ (λn. …)"
Third, {q. q ∈ {1..n/d}}
is exactly the same as {1..n/d}
, so I suggest you write it that way.
To answer your actual question: If what you have written in your question is how you wrote it in Isabelle and n
and d
are of type nat
, you should be aware that {q. q ∈ {1..n/d}}
actually means {1..real n / real d}
. If n / d > 1
, this is actually an infinite set of real numbers and probably not what you want.
What you actually want is probably the set {1..n div d}
where div
denotes division on natural numbers. This is then a finite set of natural numbers.
Then you can prove the following fairly easily:
lemma
fixes f :: "real ⇒ complex" and n d :: nat
assumes "d > 0" "d dvd n"
shows "(∑k | k ∈ {1..n} ∧ d dvd k. f (k/n)) =
(∑q∈{1..n div d}. f (q/(n/d)))"
by (rule sum.reindex_bij_witness[of _ "λk. k * d" "λk. k div d"])
(use assms in ‹force simp: div_le_mono›)+
div
and /
denote the same function, namely Rings.divide.divide
. However, /
for historic reasons (and perhaps in fond memory of Pascal), /
additionally imposes the type class restriction inverse
, i.e. it only works on types that have an inverse
function.
In most practical cases, this means that div
is a general kind of division operation on rings, whereas /
only works in fields (or division rings, or things that are ‘almost’ fields like formal power series).
If you write a / b
for natural numbers a
and b
, this is therefore a type error. The coercion system of Isabelle then infers that you probably meant to write real a / real b
and that's what you get.
It's a good idea to look at the output in such cases to ensure that the inferred coercions match what you intended.
If you apply some rule (e.g. with apply (rule …)
) and it fails and you don't understand why, there is a little trick to find out. If you add a using [[unify_trace_failure]]
before the apply
, you get an error message that indicates where exactly the unification failed. In this case, the message is
The following types do not unify:
(nat ⇒ complex) ⇒ nat set ⇒ complex
(real ⇒ complex) ⇒ real set ⇒ complex
This indicates that there is a summation over a set of reals somewhere that should be a summation over a set of naturals.