Given two typeclasses (e.g. group
and monoid
), I have seen both the subclass
and the instance
commands used to establish the fact that any group is also a monoid (i.e. the subclass relation), as shown in the example below.
The two commands seem to generate similar proof requirements, but also have some differences so that the proof for one does not work for the other sometimes. For example (Isabelle 2021):
theory test
imports Main HOL.Set
begin
declare [[show_types]] [[show_sorts]]
instance group β monoid
proof(intro_classes)
fix x::"'a::group"
have "Γ· x β (x β π¬) = Γ·x β x" by (simp add: invl neutl assoc_left)
from this show "x β π¬ = x" by (simp add: left_cancel)
qed
subclass (in group) monoid
proof
fix x::"'a::group" (* problem line*)
qed
end
The instance
command generates the following proof goal:
proof (state)
goal (1 subgoal):
1. βx::'a. x β π¬ = x
type variables:
'a :: group
, while the subclass
command generates a similar goal but without the type constraint 'a::group
:
proof (state)
goal (1 subgoal):
1. βx::'a. x β π¬ = x
variables:
neutral :: 'a
plus :: 'a β 'a β 'a
type variables:
'a :: type
So the first command fix x::"'a::group"
that worked in the instance
case no longer works for the subclass
case.
To me, the proof goal of the instance
command seems more natural, as one starts from a group
and just need to prove that it also respects the laws of monoid.
My questions are:
Are the two usages with instance/subclass supposed to be equivalent or do they express some fundamentally different facts/ideas?
If yes, when is one preferred over the other? If no, how are they different in terms of intended usage.
(I asked the same question in SO a couple of months ago, but have not received any response. Posting here to hopefully get more attention.)