问题
Post Answer Follow Up Question
Brian provided an answer with a suggested solution being to use lifting and transfer. However, I can't find enough tutorial information on lifting and transfer to know how to tweak his answer to finish off what I would need to do.
Here, I work in the dark, and use the answer given as a plug'n'play template to ask this follow up question.
The command in my initial code, typedef trivAlg = "{x::sT. x = emS}"
gives me a new type that is a subset of the mother type sT
.
I have my membership operator consts inP :: "sT => sT => bool"
, and so in my naive view of lifting and transfer, since my monoid_add
0 has been defined as being the constant emS::sT
, and I can make this statement, (emS::sT) inP emS
, I would want to do something like this:
theorem "~((0::trivAlg) inP 0)"
So, I try to use lifting to get my operator inP
to work with type trivAlg
like this:
lift_definition inP_trivAlg :: "trivAlg => trivAlg => bool"
is "% x y. (x inP y)"
by simp
theorem "~((0::trivAlg) inP 0)"
theorem "(emS::trivAlg) = emS"
However, I get type clashes with my use of theorem
because my use of type sT
and trivAlg
aren't compatible.
If the answer can be added to to show me how to get my inP
to work with type trivAlg
I would appreciate it. Or, maybe I'm way off the mark.
Preliminaries to the (Original) Question
I have my type sT
, which represents "everything is a set". So far, all my constants and operators have been defined with the single type sT
. For example, my empty set, membership operator, and union operator are defined something like this:
consts emS :: "sT"
consts inP :: "sT => sT => bool"
consts geU :: "sT => sT"
I'm now doing some early investigating into whether I can tie my sT
into the generalized groups in Groups.thy.
From the HOL document, I'm trying to get examples from sections 4.2, 4.3, and 4.4 of Groups, and 15.2 and 15.3 of Nat.
Here, I'm almost to my question, but I don't know enough to know whether I'm asking an intelligent question. What I think I know is that the solution may be with locales, sublocales, and interpretations only rather than with type classes.
I've been looking a little at locales.pdf and classes.pdf, and so I know that locales and classes are intertwined. I've also been looking at IsarMathLib to see how locales, sublocales, and interpretations are being used there.
The Question
My question is, with my trivial algebraic structure below, trivAlg
, which is a new type defined with typedef
, how can I set things up with type classes so that I can use my constants, such as emS
, inP
, and geU
listed above, with elements of type trivAlg
?
After I list the code below, I ask some questions about specific lines of code in Groups.thy.
The Code
typedef trivAlg = "{x::sT. x = emS}"
by auto
instantiation trivAlg :: zero
begin
definition trivAlg_zero:
"0 = Abs_trivAlg emS"
instance ..
end
instantiation trivAlg :: monoid_add
begin
definition plus_trivAlg:
"m + n = (Abs_trivAlg emS)"
instance proof
fix n m q :: trivAlg
show "(n + m) + q = n + (m + q)"
by(metis plus_trivAlg)
show "0 + n = n"
apply(induct n) apply(auto)
by(metis plus_trivAlg)
show "n + 0 = n"
apply(induct n) apply(auto)
by(metis plus_trivAlg)
qed
end
theorem
"((n::trivAlg) + m) + q = n + (m + q)"
by(metis plus_trivAlg)
theorem
"((0::trivAlg) + 0) = 0"
by(metis monoid_add_class.add.left_neutral)
A Subsequent Question about Groups.thy
On lines 151 to 155 in Groups.thy, there is the following code:
class semigroup_add = plus +
assumes add_assoc [algebra_simps, field_simps]: "(a + b) + c = a + (b + c)"
sublocale semigroup_add < add!: semigroup plus proof
qed (fact add_assoc)
There's no one document to teach me how to use classes, locales, sublocales, and interpretations, so I don't know exactly what this tells me.
If I want to use the semigroup_add
that's in Groups.thy, do I have the choice of using it either as a type class or a locale?
回答1:
To get the corresponding operations on type trivAlg
, probably the easiest way is to use Isabelle's Lifting package; you can then use the Transfer package to prove the class instances. Here is an example:
typedef trivAlg = "{x::sT. x = emS}"
by auto
setup_lifting type_definition_trivAlg
instantiation trivAlg :: zero
begin
lift_definition zero_trivAlg :: "trivAlg" is "emS" .
instance ..
end
instantiation trivAlg :: monoid_add
begin
lift_definition plus_trivAlg :: "trivAlg => trivAlg => trivAlg"
is "% x y. emS"
by simp
instance proof
fix n m q :: trivAlg
show "(n + m) + q = n + (m + q)"
by transfer simp
show "0 + n = n"
by transfer simp
show "n + 0 = n"
by transfer simp
qed
end
回答2:
Simple things kill me if I don't know what the syntax means, and much of learning Isabelle/HOL is "stare at multiple examples for long periods of time", which is not to say there's not a lot of documentation for Isabelle relative to other proof assistants.
Here I finish off the question I had on how to actually use what Brian gave me.
My inP
is actually binary notation for the function in_P :: sT => sT => bool
, which is what I want to lift over to type trivAlg
, though I'm not sure I just now used the term "lift" correctly.
From the Isabelle user's list, I found an example showing the lifting of the HOL union
operator. Similarly, I lift my in_P
like this:
lift_definition in_P_trivAlg :: "trivAlg => trivAlg => bool"
is "in_P :: sT => sT => bool"
by simp
In my previous trial and error attempts, I had been using my inP
, which is only notation, and it hadn't sunk in that lift_definition
is introducing a brand new function. Those those things finally occurred to me, and instead of "trial and error", I got "trial and success" by using the function in_P_trivAlg
intelligently like this:
theorem "~(in_P_trivAlg 0 0)"
by(metis
Ax_em
in_P_trivAlg.rep_eq
zero_trivAlg.rep_eq)
This says that the empty set doesn't contain itself. That's good, and tells me I'm on the right track, considering that 0 has been defined to be emS
, which is defined, with the axiom Ax_em
, to contain no elements .
I now need to figure out how to overload my membership operator notation \<in>\<^isub>\iota>
. Overloading notation hasn't been important until now, since I've had a need to not overload most standard notation, like \<in>
.
It looks like I'll have a need to rename theorems, such as in_P_trivAlg.rep_eq
, and I just got the answer for that from "Can I define multiple names for a theorem?".
From RealVector.thy, I now see that there's a lot of renaming using the lemmas
command, such as
text {* Recover original theorem names *}
lemmas scaleR_left_commute = real_vector.scale_left_commute
lemmas scaleR_zero_left = real_vector.scale_zero_left
...
The purpose of that code would have meant nothing to me if it wasn't for the Stackoveflow answer I just provided a link to.
来源:https://stackoverflow.com/questions/15889860/how-to-get-a-typedef-type-to-inherit-operators-from-its-mother-type-for-type-cla