Given a ring, together with a bijection to another set (n.b. set not type), it ought to be "trivial" to define the (unique) induced ring structure on the "other set" that makes the bijection an isomorphism. But my proof that tries to use this takes 101 lines (plus definitions and lemmas). Is there another approach using e.g. "lifting" that makes the whole thing fall out more easily?
Here's an example that could be filled in to do what I want:
theory InducedRing
imports "HOL-Algebra.QuotRing"
begin
lemma
assumes "ring โ" "bij_betw ฯ (carrier โ) S"
obtains ๐ฎ where "ring ๐ฎ" and "carrier ๐ฎ = S" and "ฯ โ ring_hom โ ๐ฎ"
sorry
end
Feel free to rewrite this to an equivalent or stronger statement (e.g., reverse the direction of \<phi>
or even assume a pair of inverse bijections, make the hypotheses part of a locale definition, assert uniqueness of \<S>
, change the names according to your own taste....)
The goal is to make the proof feel short and natural. I'm hoping there's a theorem somewhere in HOL-Algebra
or another library that will make this easy, but sledgehammer was not able to find it for me -- at least, not with this version of the statement.
I do not think you will get around proofing the ring axioms, except if someone has already proven a similar lemma. I have no experience with HOL-Algebra, so maybe there is something nicer.
Luckily automation seems to handle them fairly well (except one, where auto
needs a bit of help). I obtained the proofs by hitting the goal with auto
and sledgehammering what was left to search for relevant lemmas to add to auto
.
lemma
assumes "ring โ" "bij_betw ฯ (carrier โ) S"
obtains ๐ฎ where "ring ๐ฎ" and "carrier ๐ฎ = S" and "ฯ โ ring_hom โ ๐ฎ"
proof-
interpret โ: ring โ
using assms(1) .
(* Define the ring *)
let ?Z = "ฯ (zero โ)"
let ?O = "ฯ (one โ)"
let ?mult = "ฮปx y . ฯ (inv_into (carrier โ) ฯ x โโโโ inv_into (carrier โ) ฯ y)"
let ?add = "ฮปx y . ฯ (inv_into (carrier โ) ฯ x โโโโ inv_into (carrier โ) ฯ y)"
let ?๐ฎ = "โฆ carrier = S, mult = ?mult , one = ?O, zero = ?Z, add = ?add,
โฆ = (undefined :: 'd) โฆ :: ('c, 'd) ring_scheme"
show thesis
proof(rule that[of ?๐ฎ])
(* The only part where auto needed some help *)
have helper: "โyโS. ฯ (inv_into (carrier โ) ฯ x โโโโ inv_into (carrier โ) ฯ y) = ฯ ๐ฌโโโ"
if "x โ S" for x
using assms that by (intro bexI[where x="ฯ (โโโโ (inv_into (carrier โ) ฯ x))"])
(auto intro: bij_betw_apply
simp add: ring.ring_simprules bij_betw_imp_inj_on bij_betw_imp_surj_on inv_into_into)
show "ring ?๐ฎ"
using assms by unfold_locales
(auto intro: bij_betw_apply simp add: ring.ring_simprules bij_betw_inv_into_right
bij_betw_imp_inj_on bij_betw_imp_surj_on inv_into_into Units_def helper)
next
show "carrier ?๐ฎ = S"
by simp
next
from assms(2) show "ฯ โ ring_hom โ ?๐ฎ"
by (intro ring_hom_memI) (auto intro: bij_betw_apply simp add: bij_betw_inv_into_left)
qed
qed
In my proof (and yours as well) I explicitly give the definitions of the induced ring, which makes the obtains
in the goal statement a bit pointless in my opinion. Similarly, the S
can be computed from carrier โ
. So why not have the concrete definitions available on the toplevel, similar to for example this:
abbreviation "bij_ring โ ฯ โก โฆcarrier = ฯ ` carrier โ,
mult = ฮปx y . ฯ (inv_into (carrier โ) ฯ x โโโโ inv_into (carrier โ) ฯ y), one = ฯ (one โ),
zero = ฯ (zero โ), add = ฮปx y . ฯ (inv_into (carrier โ) ฯ x โโโโ inv_into (carrier โ) ฯ y),
โฆ = (undefined :: 'd) โฆ :: ('c, 'd) ring_scheme"
lemma
assumes "ring โ" "bij_betw ฯ (carrier โ) (ฯ ` (carrier โ))"
shows "ring (bij_ring โ ฯ)" and "ฯ โ ring_hom โ (bij_ring โ ฯ)"
proof-
interpret โ: ring โ
using assms(1) .
(* Sadly it still needs help *)
from assms have helper: "โxโcarrier โ. ฯ (y โโโโ x) = ฯ ๐ฌโโโ"
if "y โ carrier โ" for y
using that by (metis โ.add.r_inv_ex)
from assms show "ring (bij_ring โ ฯ)"
by unfold_locales (auto simp add: bij_betw_inv_into_left
โ.add.m_assoc bij_betw_imp_inj_on ring.ring_simprules Units_def helper)
from assms(2) show "ฯ โ ring_hom โ (bij_ring โ ฯ)"
by (intro ring_hom_memI) (auto intro: bij_betw_apply simp add: bij_betw_inv_into_left)
qed
This also seems to simplify the proofs a bit. Sadly there is some duplication in the goal statement, but I cannot see a way to improve this now.