Theory IArray_Addenda_QR
section‹IArray Addenda QR›
theory IArray_Addenda_QR
imports
"HOL-Library.IArray"
begin
text‹The new file about Iarrays, with different instantiations from the presented ones in the
Gauss-Jordan algorithm.
In order to make the formalisation of the QR algorithm easier, we have decided to present here some
alternative instantiatons for immutable arrays.
Let see an example. The following definition is the one presented in the Gauss-Jordan AFP entry to
sum two vectors:
‹plus_iarray A B = IArray.of_fun (λn. A!!n + B !! n) (IArray.length A)›
While the following is the one we will present in this development:
@{text [display] "plus_iarray A B =
(let length_A = (IArray.length A);
length_B= (IArray.length B);
n=max length_A length_B ;
A'= IArray.of_fun (λa. if a < length_A then A!!a else 0) n;
B'=IArray.of_fun (λa. if a < length_B then B!!a else 0) n
in IArray.of_fun (λa. A' !! a + B' !! a) n)"}
Now the sum is done up to the length of the shortest vector and it is completed with zeros up to
the length of the largest vector. This allows us to prove that iarray is an instance of
‹comm_monoid_add›, which is quite useful for the QR algorithm (we will be able to do
sums involving immutable arrays).
These are just alternative definitions of the main operations over immutable arrays. They have the
advantage of being an instance of ‹comm_monoid_add›; nevertheless, the performance is slower
and proofs become more cumbersome. The user should decide what definitions to use (the presented
here or the presented ones in the Gauss-Jordan AFP entry) depending on the algorithm to formalise.
›
lemma iarray_exhaust2:
"(xs = ys) = (IArray.list_of xs = IArray.list_of ys)"
by (metis iarray.exhaust list_of.simps)
lemma of_fun_nth:
assumes i: "i<n"
shows "(IArray.of_fun f n) !! i = f i"
unfolding IArray.of_fun_def using map_nth i by auto
subsection‹Some previous instances›
instantiation iarray :: ("{plus,zero}") plus
begin
definition plus_iarray :: "'a iarray ⇒ 'a iarray ⇒ 'a iarray"
where "plus_iarray A B =
(let length_A = (IArray.length A);
length_B= (IArray.length B);
n=max length_A length_B ;
A'= IArray.of_fun (λa. if a < length_A then A!!a else 0) n;
B'=IArray.of_fun (λa. if a < length_B then B!!a else 0) n
in
IArray.of_fun (λa. A' !! a + B' !! a) n)"
instance proof qed
end
instantiation iarray :: (zero) zero
begin
definition "zero_iarray = (IArray[]::'a iarray)"
instance proof qed
end
instantiation iarray :: (comm_monoid_add) comm_monoid_add
begin
instance
proof
fix a b c::"'a iarray"
have max_eq: "(max (IArray.length 0) (IArray.length a)) =(IArray.length a) "
proof -
have "max (length (IArray.list_of (0::'a iarray))) (length (IArray.list_of a)) = length (IArray.list_of a)"
by (metis list.size(3) list_of.simps max_0L zero_iarray_def)
thus "max (IArray.length 0) (IArray.length a) = IArray.length a"
by (metis IArray.length_def list.size(3) list_of.simps zero_iarray_def)
qed
have length0: "IArray.length 0 = 0" unfolding zero_iarray_def by auto
show "0 + a = a"
proof (unfold iarray_exhaust2 list_eq_iff_nth_eq, auto, unfold IArray.length_def[symmetric] IArray.sub_def[symmetric])
show length_eq: "IArray.length (0 + a) = IArray.length a" unfolding plus_iarray_def Let_def using max_eq by auto
fix i assume i: "i < IArray.length (0 + a)"
have i2: "i < IArray.length a" by (metis length_eq i)
have "(0 + a) !! i = (λaa. IArray.of_fun (λa. if a < 0 then 0 !! a else 0) (IArray.length a) !! aa +
IArray.of_fun (λaa. if aa < IArray.length a then a !! aa else 0) (IArray.length a) !! aa) i"
unfolding plus_iarray_def Let_def
unfolding max_eq unfolding length0 unfolding sub_def[symmetric]
by (rule of_fun_nth[OF i2])
also have "... = (λaa. 0 + IArray.of_fun (λaa. if aa < IArray.length a then a !! aa else 0) (IArray.length a) !! aa) i"
using i2 by auto
also have "... = a !! i" using i2 by simp
finally show "(0 + a) !! i = a !! i" .
qed
show "a + b = b + a"
proof (unfold iarray_exhaust2 list_eq_iff_nth_eq, auto, unfold IArray.length_def[symmetric] IArray.sub_def[symmetric])
have max_eq: "(max (IArray.length a) (IArray.length b)) = IArray.length (a + b)"
unfolding plus_iarray_def Let_def by auto
show length_eq: "IArray.length (a + b) = IArray.length (b + a)"
unfolding plus_iarray_def Let_def by auto
fix i assume i: "i < IArray.length (a + b)"
have i2: "i < IArray.length (b+a)" using i unfolding length_eq .
have i3: "i < (max (IArray.length a) (IArray.length b))" by (metis i max_eq)
have i4: "i < (max (IArray.length b) (IArray.length a))" by (metis i3 max.commute)
show "(a + b) !! i = (b + a) !! i"
unfolding plus_iarray_def Let_def
unfolding of_fun_nth[OF i3]
unfolding of_fun_nth[OF i4]
by (simp only: add.commute)
qed
show "a + b + c = a + (b + c)"
proof (unfold iarray_exhaust2 list_eq_iff_nth_eq, auto, unfold IArray.length_def[symmetric] IArray.sub_def[symmetric])
show length_eq: "IArray.length (a + b + c) = IArray.length (a + (b + c))"
unfolding plus_iarray_def Let_def by auto
fix i assume i: "i < IArray.length (a + b + c)"
have i2: "i<(max (IArray.length (IArray.of_fun (λaa. IArray.of_fun
(λaa. if aa < IArray.length a then a !! aa else 0) (max (IArray.length a) (IArray.length b)) !! aa +
IArray.of_fun (λa. if a < IArray.length b then b !! a else 0) (max (IArray.length a) (IArray.length b)) !! aa)
(max (IArray.length a) (IArray.length b))))
(IArray.length c))" using i unfolding plus_iarray_def Let_def by auto
have i3: "i< (max (IArray.length a) (IArray.length (IArray.of_fun
(λa. IArray.of_fun (λa. if a < IArray.length b then b !! a else 0) (max (IArray.length b) (IArray.length c)) !! a +
IArray.of_fun (λa. if a < IArray.length c then c !! a else 0) (max (IArray.length b) (IArray.length c)) !! a)
(max (IArray.length b) (IArray.length c)))))"
using i unfolding plus_iarray_def Let_def by auto
show "(a + b + c) !! i = (a + (b + c)) !! i"
unfolding plus_iarray_def unfolding Let_def
unfolding of_fun_nth[OF i2]
unfolding of_fun_nth[OF i3]
using i2 i3
by (auto simp add: add.assoc)
qed
qed
end
instantiation iarray :: (uminus) uminus
begin
definition uminus_iarray :: "'a iarray ⇒ 'a iarray"
where "uminus_iarray A = IArray.of_fun (λn. - A!!n) (IArray.length A)"
instance proof qed
end
instantiation iarray :: ("{minus,zero}") minus
begin
definition minus_iarray :: "'a iarray ⇒ 'a iarray ⇒ 'a iarray"
where "minus_iarray A B =
(let length_A= (IArray.length A);
length_B= (IArray.length B);
n=max length_A length_B ;
A'= IArray.of_fun (λa. if a < length_A then A!!a else 0) n;
B'=IArray.of_fun (λa. if a < length_B then B!!a else 0) n
in
IArray.of_fun (λa. A' !! a - B' !! a) n)"
instance proof qed
end
subsection‹Some previous definitions and properties for IArrays›
subsubsection‹Lemmas›
subsubsection‹Definitions›
fun all :: "('a ⇒ bool) ⇒ 'a iarray ⇒ bool"
where "all p (IArray as) = (ALL a : set as. p a)"
hide_const (open) all
fun exists :: "('a ⇒ bool) ⇒ 'a iarray ⇒ bool"
where "exists p (IArray as) = (EX a : set as. p a)"
hide_const (open) exists
subsection‹Code generation›
code_printing
constant "IArray_Addenda_QR.exists" ⇀ (SML) "Vector.exists"
| constant "IArray_Addenda_QR.all" ⇀ (SML) "Vector.all"
end