Proving Groups with Idris

Exactly a year ago, in one of my previous posts, we proved Monoid laws with Idris. We’ll do the same with Groups.

A Group is an algebraic structure defined on a set G with an operation * denoted (G, *), which satisfies these laws:

1. a, b \in G \implies a * b \in G – closure
2. (a * b) * c = a * (b * c) – associativity
3. \exists e \forall a, e * a = a = a * e – identity
4. \forall a \exists a^{-1}, a * a^{-1} = e \land a^{-1} * a = e – inverse

Note that a Group is just a Monoid with an inverse. To abstract them in Idris, we will use a type constraint on our previously defined ProvenMonoid:

interface (ProvenMonoid m) => ProvenGroup m where
    minverse : m -> m
    inverseProofL : (a : m) -> mappend a (minverse a) = Main.mempty
    inverseProofR : (a : m) -> mappend (minverse a) a = Main.mempty

We will mathematically prove that (\mathbb{Z}, +) is a Group:

1. Adding any two integers produces an integer
2. We use induction on c. Base case is trivial, so we proceed to use the inductive hypothesis as follows: a+(b+(c+1)) \\ = (a+(b+c))+1 \\  = ((a+b)+c)+1 \\ = (a+b)+(c+1)
3. e = 0 since \forall a, 0 + a = a = a + 0
4. a + x = x + a = 0 \\ a + x = 0 \\ x = -a

We will do the same proof in Idris. First, we’ll prove that the operation forms a Monoid. We’ll use Data.ZZ for that since we want to use integers, not naturals. For this, you will have to run the REPL as idris test.idr -p contrib:

implementation ProvenMonoid ZZ where
    mappend x y = x + y
    mempty      = Pos Z

    assocProof  = plusAssociativeZ
    idProofL    = plusZeroLeftNeutralZ
    idProofR    = plusZeroRightNeutralZ

Pretty similar to naturals. What about Group?

implementation ProvenGroup ZZ where
    minverse      = negate

    inverseProofL = plusNegateInverseLZ
    inverseProofR = plusNegateInverseRZ

Cool stuff, right? 🙂

3 thoughts on “Proving Groups with Idris

Leave a reply to Boro Sitnikovski Cancel reply