Proof of Paper, Scissor, Rock as Monoid Instance in Coq -
so while learning coq did simple example game paper, scissor, rock. defined data type.
inductive psr : set := paper | scissor | rock.
and 3 functions:
definition me (elem: psr) : psr := elem. definition beats (elem: psr) : psr := match elem | paper => scissor | rock => paper | scissor => rock end. definition beatenby (elem: psr) : psr := match elem | paper => rock | rock => scissor | scissor => paper end.
i define composition (although should somewhere in standard library)
definition compose {a b c} (g : b -> c) (f : -> b) : (a -> c) := fun x : => g (f x).
i implement class monoid described here
class monoid {a : type} (dot : -> -> 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 managed prove can psr
forms monoid under compose
+
, me
1
instance mspr : monoid compose me. split. intros. reflexivity. intros. reflexivity. intros. reflexivity. qed.
question
why proof of instance mspr : monoid compose me.
work applying intros
, reflexivity
? honestly, did split
, intros
knowing doing, after intros
got 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.
didn't work. magically reflexivity.
solved don't know why.
side note
this worked wonderfully, if define power this
fixpoint power {a dot one} {m : @monoid dot one}(a:a)(n:nat) := match n 0 % nat => 1 | s p => dot (power p) end.
then compute (power beats 2) paper.
yields
= rock : psr
which did beats (beats paper) = beats scissor = rock
!!!
the reflexivity principle in coq more powerful than mere syntactic equality, 1 expect. speaking, coq considers equal 2 things can simplified same value. simplification here taken in more restrictive sense in algebra, instance, 1 allowed manipulate formulas according algebraic laws. instead, coq comes fixed set of computation rules describe how programs compute. in example, simplifying expression yield
compose x (fun => y (z a)) = compose (fun => x (y a)) z fun => x (y (z a)) = fun => x (y (z a))
where "fun" coq's notation anonymous function, i.e. function without name. since these 2 things equal, reflexivity suffices. same idea apllies other goals.
Comments
Post a Comment