Theory Int_LSBF
theory Int_LSBF
imports Nat_LSBF "HOL-Algebra.IntRing"
begin
section "Representing @{type int} in LSBF"
subsection "Type definition"
datatype sign = Positive | Negative
type_synonym int_lsbf = "sign × nat_lsbf"
subsection "Conversions"
fun from_int :: "int ⇒ int_lsbf" where
"from_int x = (if x ≥ 0 then (Positive, from_nat (nat x)) else (Negative, from_nat (nat (-x))))"
fun to_int :: "int_lsbf ⇒ int" where
"to_int (Positive, xs) = int (to_nat xs)"
| "to_int (Negative, xs) = - int (to_nat xs)"
lemma to_int_from_int[simp]: "to_int (from_int x) = x"
by (cases "x ≥ 0") simp_all
fun truncate_int :: "int_lsbf ⇒ int_lsbf" where
"truncate_int (Positive, xs) = (Positive, truncate xs)"
| "truncate_int (Negative, xs) = (let ys = truncate xs in if ys = [] then (Positive, []) else (Negative, ys))"
lemma to_int_truncate[simp]: "to_int (truncate_int xs) = to_int xs"
by (induction xs rule: truncate_int.induct) (simp_all add: Let_def to_nat_zero_iff)
lemma truncate_from_int[simp]: "truncate_int (from_int x) = from_int x"
apply (cases "x ≥ 0")
subgoal by simp
subgoal unfolding Let_def
proof -
assume "¬ x ≥ 0"
then have "to_nat (from_nat (nat (- x))) > 0" by simp
then have "truncate (from_nat (nat (- x))) ≠ []" using to_nat_zero_iff nless_le by blast
then show ?thesis by simp
qed
done
lemma pos_and_neg_imp_zero:
assumes "to_int (Positive, x) = to_int (Negative, y)"
shows "to_nat x = 0 ∧ to_nat y = 0"
proof -
have "to_int (Positive, x) ≥ 0" "to_int (Negative, y) ≤ 0" by simp_all
with assms have "to_int (Positive, x) = 0" "to_int (Negative, y) = 0" by simp_all
thus ?thesis by simp_all
qed
lemma to_int_eq_imp_truncate_int_eq: "to_int (a, x) = to_int (b, y) ⟹ truncate_int (a, x) = truncate_int (b, y)"
apply (cases a; cases b)
subgoal by (simp add: to_nat_eq_imp_truncate_eq[of x y])
subgoal
using pos_and_neg_imp_zero[of x y] to_nat_zero_iff
by fastforce
subgoal using to_nat_zero_iff by (simp add: Let_def)
subgoal by (simp add: to_nat_eq_imp_truncate_eq[of x y])
done
lemma from_int_to_int: "from_int ∘ to_int = truncate_int"
proof -
have "(⋀x y. to_int x = to_int y ⟹ truncate_int x = truncate_int y)"
using to_int_eq_imp_truncate_int_eq by auto
thus ?thesis
using from_to_f_criterion[of to_int from_int truncate_int]
using truncate_from_int to_int_from_int
using comp_apply
by fastforce
qed
interpretation int_lsbf: abstract_representation from_int to_int truncate_int
proof
show "to_int ∘ from_int = id"
using to_int_from_int comp_apply by fastforce
next
show "from_int ∘ to_int = truncate_int"
using from_int_to_int comp_apply by fastforce
qed
subsection "Addition"
fun add_int :: "int_lsbf ⇒ int_lsbf ⇒ int_lsbf" where
"add_int (Negative, xs) (Negative, ys) = (Negative, add_nat xs ys)"
| "add_int (Positive, xs) (Positive, ys) = (Positive, add_nat xs ys)"
| "add_int (Positive, xs) (Negative, ys) = (if compare_nat xs ys then (Negative, subtract_nat ys xs) else (Positive, subtract_nat xs ys))"
| "add_int (Negative, xs) (Positive, ys) = (if compare_nat xs ys then (Positive, subtract_nat ys xs) else (Negative, subtract_nat xs ys))"
lemma add_int_correct: "to_int (add_int x y) = to_int x + to_int y"
apply (induction x y rule: add_int.induct)
subgoal by (simp add: add_nat_correct)
subgoal by (simp add: add_nat_correct)
apply (auto simp only: add_int.simps compare_nat_correct subtract_nat_correct to_int.simps split: if_splits)
done
fun nat_mul_to_int_mul :: "(nat_lsbf ⇒ nat_lsbf ⇒ nat_lsbf) ⇒ int_lsbf ⇒ int_lsbf ⇒ int_lsbf" where
"nat_mul_to_int_mul f (x, xs) (y, ys) = ((if x = y then Positive else Negative), f xs ys)"
lemma nat_mul_to_int_mul_correct:
assumes "⋀x y. to_nat (f x y) = to_nat x * to_nat y"
shows "⋀x y xs ys. to_int (nat_mul_to_int_mul f (x, xs) (y, ys)) = to_int (x, xs) * to_int (y, ys)"
subgoal for x y xs ys
by (cases x; cases y) (simp_all add: assms)
done
subsection "Grid Multiplication"
fun grid_mul_int where "grid_mul_int x y = nat_mul_to_int_mul grid_mul_nat x y"
corollary grid_mul_int_correct: "to_int (grid_mul_int x y) = to_int x * to_int y"
using nat_mul_to_int_mul_correct[OF grid_mul_nat_correct]
by (metis grid_mul_int.elims surj_pair)
end