Isabelle confused by a previous lemma? - debugging

I found something strange while doing exercise 2.5 of the Concrete Semantics book. Basically, we have to prove the famous Gauss formula for the sum n integers. Here is my code:
fun sum_upto :: "nat ⇒ nat" where
"sum_upto 0 = 0" |
"sum_upto (Suc n) = (Suc n) + (sum_upto n)"
lemma gauss: "sum_upto n = (n * (n + 1)) div 2"
apply(induction n)
apply(auto)
done
This won't proceed at least I remove a previous lemma from exercise 2.3:
fun double :: "nat ⇒ nat" where
"double 0 = 0" |
"double (Suc n) = add (double n) 2"
lemma double_succ [simp]: "Suc (Suc (m)) = add m 2"
apply(induction m)
apply(auto)
done
lemma double_add: "double m = add m m"
apply(induction m)
apply(auto)
done
So here add is a user-defined function for addition. I've looked other solutions and my definition of double is substituted by Suc(Suc (double n)) in that case, the next lemma is unnecessary and the error in Gauss disappears.
However, I'm interested to know why is this happening because in principle both problems don't use any common structure.

The [simp] is at fault here. Try removing it and see if that helps.
The underlying reason is that [simp] will add a rule to the so-called simpset and will be used by the simp, auto, etc. methods automatically. Great care needs to be taken before lemmas are declared as [simp] because of that.
In your case, the problem is that Suc (Suc m) = add m 2 is not a good rule for the simpset. It will replace all instances of Suc (Suc m) with add m 2, which is probably the opposite direction of what you want.

Related

How in Coq to use mod arithmetic (specifically Zplus_mod theorem) for natural numbers?

I want to apply the library theorem:
Theorem Zplus_mod: forall a b n, (a + b) mod n = (a mod n + b mod n) mod n.
where a b n are expected to have the type Z.
I have a subexpression (a + b) mod 3 in my goal, with a b : nat.
rewrite Zplus_mod gives an error Found no subterm matching
rewrite Zplus_mod with (a := a) gives an error "a" has type "nat" while it is expected to have type "Z".
Since natural numbers are also integers, how to use Zplus_mod theorem for nat arguments?
You can't apply this theorem, because the notation mod refers to a function on natural numbers Nat.modulo in a context where you are using natural numbers, while the notation mod refers to Z.modulo when you are referring to integers of type Z.
Using the Search command ou can search specifically for theorems about Nat.modulo and (_ + _)%nat and you will see that some existing theorems are actually close to your needs (Nat.add_mod_idemp_l and Nat.add_mod_idemp_r).
You can also look for a theorem that links Z.modulo and Nat.modulo. This gives mod_Zmod. But this forces you to work in the type of integers:
Require Import Arith ZArith.
Search Z.modulo Nat.modulo.
(* The answer is :
mod_Zmod: forall n m, m <> 0 -> Z.of_nat (n mod m) =
(Z.of_nat n mod Z.of_nat m)%Z *)
One way out is to find a theorem that tells you that the function Z.of_nat is injective. I found it by typing the following command.
Search Z.of_nat "inj".
In the long list that was produced, the relevant theorem is Nat2Z.inj, you
then need to show how Z.of_nat interacts with all of the operators involved. Most of these theorems require n to be non-zero, so I add this as a condition. Here is the example.
Lemma example (a b n : nat) :
n <> 0 -> (a + b) mod n = (a mod n + b mod n) mod n.
Proof.
intro nn0.
apply Nat2Z.inj.
rewrite !mod_Zmod; auto.
rewrite !Nat2Z.inj_add.
rewrite !mod_Zmod; auto.
rewrite Zplus_mod.
easy.
Qed.
This answers your question, but frankly, I believe you would be better off using the lemmas Nat.add_mod_idemp_l and Nat.add_mod_idemp_r.

Proving equivalence of well-founded recursion

In answer to this question Assisting Agda's termination checker the recursion is proven to be well-founded.
Given the function defined like so (and everything else like in Vitus's answer there):
f : ℕ → ℕ
f n = go _ (<-wf n)
where
go : ∀ n → Acc n → ℕ
go zero _ = 0
go (suc n) (acc a) = go ⌊ n /2⌋ (a _ (s≤s (/2-less _)))
I cannot see how to prove f n == f ⌊ n /2⌋. (My actual problem has a different function, but the problem seems to boil down to the same thing)
My understanding is that go gets Acc n computed in different ways. I suppose, f n can be shown to pass Acc ⌊ n /2⌋ computed by a _ (s≤s (/2-less _)), and f ⌊ n /2⌋ passes Acc ⌊ n /2⌋ computed by <-wf ⌊ n /2⌋, so they cannot be seen identical.
It seems to me proof-irrelevance must be used somehow, to say that it's enough to just have an instance of Acc n, no matter how computed - but any way I try to use it, it seems to contaminate everything with restrictions (eg pattern matching doesn't work, or irrelevant function cannot be applied, etc).

Determining which integer is closest to the kth root of n without using floating point arithmetic?

Suppose that I want to compute k√n rounded to the nearest integer, where n and k are nonnegative integers. Using binary search, I can find an integer a such that
ak ≤ n < (a+1)k.
This means that either a or a+1 is the kth root of n rounded to the nearest integer. However, I'm not sure how to determine which one it is without doing some calculations that involve floating-point arithmetic.
Given the values of a, n, and k, is there a way to determine the kth root of n rounded to the nearest integer without doing any floating-point calculations?
Thanks!
2kak < 2kn < (2a+1)k → (dividing by 2k) ak < n < (a+0.5)k → (taking the kth root) a < k√n < a+0.5, so the kth root of n is closer to a than to a+1. Note that the edge case will not occur; the kth root of an integer can not be an integer plus 0.5 (a+0.5) as the kth roots of n which are not kth powers are irrational and if n were a perfect kth power, then the kth root would be an integer.
The answers by Ramchandra Apte and Lazarus both contain what seems to be the essence of the correct answer, but both are also (at least to me) a bit hard to follow. Let me try to explain the trick they seem to be getting at, as I understand it, a bit more clearly:
The basic idea is that, to find out whether a or a+1 is closer to k√n, we need to test whether k√n < a+½.
To get rid of the ½, we can simply multiply both sides of this inequality by 2, giving 2·k√n < 2a+1, and by raising both sides to the k-th power (and assuming they're both positive) we get the equivalent inequality 2k·n < (2a+1)k. So, at least as long as 2k·n = n &ll; k does not overflow, we can simply compare it with (2a+1)k to obtain the answer.
In fact, we could simply compute b = ⌊ k√(2k·n) ⌋ to begin with. If b is even, then the closest integer to k√n is b / 2; if b is odd, it is (b + 1) / 2. Indeed, we can combine the two cases and say that the closest integer to k√n is ⌊ (b+1) / 2 ⌋, or, in pseudo-C:
int round_root( int k, int n ) {
int b = floor_root( k, n << k );
return (b + 1) / 2;
}
Ps. An alternative approach could be to compute an approximation (a+½)k directly using the binomial theorem as
(a+½)k
= ∑i=0..k (k choose i) ak−i / 2i
&approx; ak
+ k·ak−1 / 2 + ... and compare it directly with n. However, at least naïvely, summing all the terms of the binomial expansion would still require keeping track of k extra bits of precision (or at least k−1; I believe the last term can be safely neglected), so it may not gain much over the method suggested above.
My guess is that you want to use this algorithm on an FPGA/CPLD, or a processor with limited resources, since your approach reminds me of CORDIC. Hence, I will give a solution with that in mind.
When you reach a^k ≤ n < (a+1)^k, it means that floor of x=root(n,k) is 'a'. In other words, x = a + f, where 0=<f<0.5. Thus, multiplying the equation by 2, you will have 2x=2a+2f. It basically means that floor(2x) = 2a (since 2f<1). Now, x = √n (kth root), thus 2x = k√((2^k)*n) (kth root). So, just shift n by k bits to left, then calculate its kth root with your algorithm. If its lower bound was exactly 2 times kth root of n, then kth root of n is a, otherwise it is a+1.
Assuming you have a function that gives you the lower bound of the kth root of n (rootk(n)), the final result, using binary operators and with C notations, would be:
closestint = a + ((rootk(n) << 1) == rootk(n>>k) );
Compute the cube of (a + 0.5)*10 (or 10a + 5 - no floating point arithmetic), then divide it by 1000.
Then check on which side the number is.
The idea of multiplying by 10 is to shift the decimal place one position to the right. Then we divide by 1000 because we multiplied by 10 3 times because of the cubing.
For example:
Input: 16
a = 2
a+1 = 3
a^3 = 8
(a+1)^3 = 27
10a + 5 = 25
25^3 = 15625
floor(15625 / 1000) = 15
16 > 15, thus 3 is closer.
It would also work to, as Oli pointed out, compute the cube of (a + 0.5)*2 (or 2a + 1), then divide it by 8.
For example:
2a + 1 = 5
5^3 = 125
floor(125 / 8) = 15
16 > 15, thus 3 is closer.
You can use Newton's method to find a; it works perfectly well with integers, and is faster than binary search. Then compute ak and (a+1)k using the square-and-multiply powering algorithm. Here's some code, in Scheme because I happened to have that handy:
(define (iroot k n) ; largest integer x such that x ^ k <= n
(let ((k-1 (- k 1)))
(let loop ((u n) (s (+ n 1)))
(if (<= s u) s
(loop (quotient (+ (* k-1 u) (quotient n (expt u k-1))) k) u)))))
(define (ipow b e) ; b^e
(if (= e 0) 1
(let loop ((s b) (i e) (a 1)) ; a * s^i = b^e
(let ((a (if (odd? i) (* a s) a)) (i (quotient i 2)))
(if (zero? i) a (loop (* s s) i a))))))
To determine which of ak and (a+1)k is closer to the root, you could use the powering algorithm to compute (a + 1/2)k — it's an exact calculation that the square-and-multiply operation can perform — then compare the result to n and determine which side is closer.
Edit: -
Sorry of misunderstanding the problem. Here is a possible solution of original question :-
Use newtons approximation theorem : -
here = means (approximately = )
f(b+a) = f(b) + a*f'(b)
a -> 0
f(x) = x^k
f'(x) = k*x^(k-1)
hence using above equation
f(a+0.5) = a^k + 1/2*k*a^(k-1);
need to check n < f(a+0.5)
n < a^k + 1/2*k*a^(k-1)
rearranging (n-a^k)*2 < k*a^(k-1)
Note: you can use binomial theorem to get more precision.
Think. Ideally, you'd do one more step of binary search, to see which side of a+½ the root lies. That is, test the inequality
(a+0.5)k < n
But the left hand side is difficult to compute precisely (floating point issues). So write down an equivalent inequality in which all the terms are integers:
(2a+1)k < 2k n
Done.

Isabelle matrix arithmetic: det_linear_row_setsum in library with different notation

I recently started using the Isabelle theorem prover. As I want to prove another lemma, I would like to use a different notation than the one used in the lemma "det_linear_row_setsum", which can be found in the HOL library. More specifically, I would like to use the "χ i j notation" instead of "χ i". I have been trying to formulate an equivalent expression for some time, but couldn't figure it out yet.
(* ORIGINAL lemma from library *)
(* from HOL/Multivariate_Analysis/Determinants.thy *)
lemma det_linear_row_setsum:
assumes fS: "finite S"
shows "det ((χ i. if i = k then setsum (a i) S else c i)::'a::comm_ring_1^'n^'n) = setsum (λj. det ((χ i. if i = k then a i j else c i)::'a^'n^'n)) S"
proof(induct rule: finite_induct[OF fS])
case 1 thus ?case apply simp unfolding setsum_empty det_row_0[of k] ..
next
case (2 x F)
then show ?case by (simp add: det_row_add cong del: if_weak_cong)
qed
..
(* My approach to rewrite the above lemma in χ i j matrix notation *)
lemma mydet_linear_row_setsum:
assumes fS: "finite S"
fixes A :: "'a::comm_ring_1^'n^'n" and k :: "'n" and vec1 :: "'vec1 ⇒ ('a, 'n) vec"
shows "det ( χ r c . if r = k then (setsum (λj .vec1 j $ c) S) else A $ r $ c ) =
(setsum (λj . (det( χ r c . if r = k then vec1 j $ c else A $ r $ c ))) S)"
proof-
show ?thesis sorry
qed
First, make yourself clear what the original lemma says: a is a family of vectors indexed by i and j, c is a family of vectors indexed by i. The k-th row of the matrix on the left is the sum of the vectors a k j ranged over all j from the set S.
The other rows are taken from c. On the right, the matrices are the same except that row k is now a k j and the j is bound in the outer sum.
As you have realised, the family of vectors a is only used for the index i = k, so you can replace a by %_ j. vec1 $ j. Your matrix A yields the family of rows, i.e., c becomes %r. A $ r. Then, you merely have to exploit that (χ n. x $ n) = x (theorem vec_nth_inverse) and push the $ through the if and setsum. The result looks as follows:
lemma mydet_linear_row_setsum:
assumes fS: "finite S"
fixes A :: "'a::comm_ring_1^'n^'n" and k :: "'n" and vec1 :: "'vec1 => 'a^'n"
shows "det (χ r c . if r = k then setsum (%j. vec1 j $ c) S else A $ r $ c) =
(setsum (%j. (det(χ r c . if r = k then vec1 j $ c else A $ r $ c))) S)"
To prove this, you just have to undo the expansion and the pushing through, the lemmas if_distrib, cond_application_beta, and setsum_component might help you in doing so.

Isabelle: proof for a equality of transposed matrix with a constant factor

I am facing problems with the following lemma, which I think should be correct. I can get the proof to work up to a certain point with small steps, however I haven't found a way to proof the entire lemma.
lemma abc:
fixes A :: "'a::comm_ring_1^'n^'n" and l :: 'n and c :: 'a
shows "(χ i j. if i = l then c * (transpose A $ i $ j) else (transpose A $ i $ j)) =
(χ i j. if i = l then c * (A $ j $ i) else (A $ j $ i))"
proof -
(* here is my draft *)
have th1: "(χ i j. transpose A $ i $ j) = (χ i j. A $ j $ i)"
by (simp add: det_transpose transpose_def)
have "(χ i j. if i = l then (transpose A $ i $ j) else (transpose A $ i $ j)) =
(χ i j. A $ j $ i)" by (metis column_def row_def row_transpose)
show ?thesis sorry
qed
Before even starting to prove something in Isabelle, you should know how to prove it on paper (also experienced Isabelle users do not always heed their own advice ;)). If you know how to prove it on paper, it might still not be obvious how to translate the paper proof into Isabelle/Isar. However, it would make it easier to help (and show that you understand the mathematical problem at hand, which has nothing to do with Isabelle per se).
In the following I'll explain how I would approach this kind of proof:
lemma abc:
fixes A :: "'a::comm_ring_1^'n^'n" and l :: 'n and c :: 'a
shows "(χ i j. if i = l then c * (transpose A $ i $ j) else (transpose A $ i $ j)) =
(χ i j. if i = l then c * (A $ j $ i) else (A $ j $ i))"
The first thing I noted is the abstractions χ i j. .... If I would prove something about plain lambda abstractions, I would definitely want to get rid of those as a first step, e.g., in order to prove that two functions f and g are equal, I would prove that f x = g x for all x. Which is expressed in Isabelle by the rule
ext: (⋀x. ?f x = ?g x) ⟹ ?f = ?g
Since I do not know much about Multivariate_Analysis I try to find a similar rule involving χ, by
find_theorems "(χ i. ?f i) = (χ i. ?g i)"
where the first hit is what I was searching for, i.e.,
Determinants.Cart_lambda_cong: (⋀x. ?f x = ?g x) ⟹ vec_lambda ?f = vec_lambda ?g
So I start the proof by applying this rule twice (with intro rule-name, the introduction rule rule-name is applied as often as possible):
proof (intro Cart_lambda_cong)
Now I have to show that for arbitrary i and j the statement holds when substituted for the χ parameters, i.e.,
fix i j
show "(if i = l then c * (transpose A $ i $ j) else (transpose A $ i $ j)) =
(if i = l then c * (A $ j $ i) else (A $ j $ i))"
Then the prove is finished by applying the definition of transpose:
by (simp add: transpose_def)
qed
Or instead of the above step-wise proof we could do
by (auto intro!: Cart_lambda_cong simp: transpose_def)
where the ! after intro tells the system that this rule should be applied aggressively (it does not work without the !, but don't ask me why ;), we would have to check the trace of applied rules to find out).
Looking at the lemma reveals that transpose A $ i $ j = A $ j $ i holds for all A,i,j, which can be easily proven by the simplifier:
lemma transpose_eq: "⋀i j. transpose A $ i $ j = A $ j $ i" by (simp add: transpose_def)
If we apply this equation manually with the subst method, your lemma can be solved easily
be just rewriting the branches of the if expression:
lemma abc:
fixes A :: "'a::comm_ring_1^'n^'n" and l :: 'n and c :: 'a
shows "(χ i j. if i = l then c * (transpose A $ i $ j) else (transpose A $ i $ j)) =
(χ i j. if i = l then c * (A $ j $ i) else (A $ j $ i))"
apply (subst transpose_eq)
apply (subst transpose_eq)
apply (rule refl)
done
So, instead of subst we should be able to use the simplifier with apply (simp add: transpose_eq), right? The reason it does not work is due to congruence rules. Basically, the simplifier knows a rule (if_weak_cong), which explicitly forbids it to simplify the branches of an if expression (this is often a good idea to keep goals on a managable size). So we need to remove this rule:
apply (simp add: transpose_def cong del: if_weak_cong)
solves your original lemma.
For a more in-depth answer see "Why won't Isabelle simplify the body of my "if _ then _ else" construct?".

Resources