How to get a typedef type to inherit operators from its mother type for type classes

二次信任 提交于 2019-12-22 09:26:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!