So while learning Coq I did a simple example with the game paper, scissor, rock. I defined a data type.
Inductive PSR : Set := paper | scissor | rock.
And three functions:
Definition me (elem: PSR) : PSR := elem.
Definition beats (elem: PSR) : PSR :=
match elem with
| paper => scissor
| rock => paper
| scissor => rock
end.
Definition beatenBy (elem: PSR) : PSR :=
match elem with
| paper => rock
| rock => scissor
| scissor => paper
end.
I also define composition (although this should be somewhere in the standard library)
Definition compose {A B C} (g : B -> C) (f : A -> B) : (A -> C) :=
fun x : A => g (f x).
I implement the class monoid as described here
Class Monoid {A : Type} (dot : A -> A -> A) (unit : A) : Type := {
dot_assoc : forall x y z:A,
dot x (dot y z)= dot (dot x y) z;
unit_left : forall x,
dot unit x = x;
unit_right : forall x,
dot x unit = x
}.
I finally managed to prove that you can PSR
forms a monoid under compose
as +
and me
as 1
Instance MSPR : Monoid compose me.
split.
intros. reflexivity.
intros. reflexivity.
intros. reflexivity.
Qed.
Question
Why does the proof of Instance MSPR : Monoid compose me.
work just by applying intros
and reflexivity
? Honestly, I did split
and intros
knowing what I was doing, but after intros
I got something like
3 subgoal
x : PSR -> PSR
y : PSR -> PSR
z : PSR -> PSR
______________________________________(1/3)
compose x (compose y z) = compose (compose x y) z
tried apply compose.
but it didn't work. Magically reflexivity.
solved it but I don't know why.
Side Note
This worked wonderfully, if you define power like this
Fixpoint power {A dot one} {M : @Monoid A dot one}(a:A)(n:nat) :=
match n with 0 % nat => one
| S p => dot a (power a p)
end.
then Compute (power beats 2) paper.
yields
= rock
: PSR
which did this beats (beats paper) = beats scissor = rock
!!!