Example Gatlab session

Declaring theories

using Gatlab

@theory Groupoid <: ThEmpty begin
  Ob :: TYPE
  Hom(dom, codom) :: TYPE  [dom::Ob, codom::Ob]

  id(a) :: Hom(a, a)  [a::Ob]
  (f  g) :: Hom(a, c)  [a::Ob, b::Ob, c::Ob, f::Hom(a,b), g::Hom(b,c)]
  inv(f) :: Hom(b,a)  [a::Ob, b::Ob, f::Hom(a,b)]

  assoc := ((f  g)  h) == (f  (g  h)) :: Hom(a,d)  [a::Ob, b::Ob, c::Ob, d::Ob, f::Hom(a,b), g::Hom(b,c), h::Hom(c,d)]
  idl := id(a)  f == f :: Hom(a,b)  [a::Ob, b::Ob, f::Hom(a,b)]
  idr := f  id(b) == f :: Hom(a,b)  [a::Ob, b::Ob, f::Hom(a,b)]
  linv := inv(f)  f == id(b) :: Hom(b,b)  [a::Ob, b::Ob, f::Hom(a,b)]
  rinv := f  inv(f) == id(a) :: Hom(a,a)  [a::Ob, b::Ob, f::Hom(a,b)]
end

gettheory(Groupoid) # hide
############
# Groupoid #
############

Type Constructors
=================
     
-----------  Ob introduction
 Ob : TYPE

    (dom,codom):Ob
-----------------------  Hom introduction
 Hom(dom,codom) : TYPE


Term Constructors
=================
       a:Ob
------------------  id introduction
 id(a) : Hom(a,a)

 (a,b,c):Ob | f:Hom(a,b) | g:Hom(b,c)
--------------------------------------  ⋅ introduction
          (f ⋅ g) : Hom(a,c)

 (a,b):Ob | f:Hom(a,b)
-----------------------  inv introduction
   inv(f) : Hom(b,a)


Axioms
======
 (a,b,c,d):Ob | f:Hom(a,b) | g:Hom(b,c) | h:Hom(c,d)
-----------------------------------------------------  assoc
      ((f ⋅ g) ⋅ h) = (f ⋅ (g ⋅ h)) : Hom(a,d)

   (a,b):Ob | f:Hom(a,b)
----------------------------  idl
 (id(a) ⋅ f) = f : Hom(a,b)

   (a,b):Ob | f:Hom(a,b)
----------------------------  idr
 (f ⋅ id(b)) = f : Hom(a,b)

      (a,b):Ob | f:Hom(a,b)
---------------------------------  linv
 (inv(f) ⋅ f) = id(b) : Hom(b,b)

      (a,b):Ob | f:Hom(a,b)
---------------------------------  rinv
 (f ⋅ inv(f)) = id(a) : Hom(a,a)

Declaring morphisms

conjugate = @context_map Groupoid [a::Ob, f::Hom(a,a)] [x::Ob, y::Ob, g::Hom(x,y), h::Hom(y,y)] begin
  a = x
  f = g  h  inv(g)
end

Declaring models

module GLImpl
using LinearAlgebra

# check objects
check(i::Int) = true

# check morphisms
check(A::Matrix) = dom(A) == codom(A) && det(A) != 0

dom(A::Matrix) = size(A)[1]

codom(A::Matrix) = size(A)[2]

(A  B) = A * B

inv(A) = Base.inv(A)

end

@simple_model Groupoid GL GLImpl

Using morphisms with models

rotate(θ) = [cos(θ) -sin(θ); sin(θ) cos(θ)]

flip = [1 0; 0 -1]

interpret(GL(), conjugate, (2, 2, flip, rotate(π/3))) == (2, rotate(-π/3))
true