diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Change log
+
+csa uses [Semantic Versioning][].
+The change log is available through the [releases on GitHub][].
+
+[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
+[releases on GitHub]: https://github.com/githubuser/csa/releases
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+Copyright (C) 2018 Jens Egholm Pedersen
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+# Connection-set algebra (CSA) library
+
+A library for constructing connection matrices between two collections of
+elements. Inspired by Mikael Djurfeldt's article from 2012 ([Neuroinformatics](https://doi.org/10.1007/s12021-012-9146-1)).
+
+## Introduction
+Connection-set algebra is a powerful algebra for describing connections between
+two elements.
+This library provides a syntax tree for modeling the set operations, as well as
+a means to transform the operations into adjacency matrices.
+
+## Installation
+This is a library and not an executable.
+Clone the repository, enter it and run `stack build` (requires [stack](http://haskellstack.org/)).
+
+## Connection-set algebra (CSA)
+Say that you have two nodes that connect to each other.
+In a adjacency matrix this can be described as a full connection like so:
+
+        1 2
+      + ———
+    1 | 1 1
+    2 | 1 1
+
+In CSA this is simply an `AllToAll` connection.
+Similarly a `OneToOne` connection describes the following adjacency matrix:
+
+        1 2
+      + ———
+    1 | 1 0
+    2 | 0 1
+
+And here is the algebra part: If we say `AllToAll - OneToOne` we get:
+
+        1 2
+      + ———
+    1 | 0 1
+    2 | 1 0
+
+## Contact
+Jens Egholm <jensegholm@protonmail.com>
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,7 @@
+-- This script is used to build and install your package. Typically you don't
+-- need to change it. The Cabal documentation has more information about this
+-- file: <https://www.haskell.org/cabal/users-guide/installing-packages.html>.
+import qualified Distribution.Simple
+
+main :: IO ()
+main = Distribution.Simple.defaultMain
diff --git a/csa.cabal b/csa.cabal
new file mode 100644
--- /dev/null
+++ b/csa.cabal
@@ -0,0 +1,62 @@
+-- This file has been generated from package.yaml by hpack version 0.28.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 1af8fc7f9a2c6a29dbc50f13e65b27c78c9af0950a1227bd2edb7758f8a977ed
+
+name:           csa
+version:        0.1.0
+synopsis:       Connection-set algebra (CSA) library
+description:    Library for algebraic connection-set expressions, built on M. Djurfeldt's idea of connection-set algebra [1]. 
+                .
+                 1: Mikael Djurfeldt. The Connection-set Algebra: a formalism for the representation of connectivity structure in neuronal network models, implementations in Python and C++, and their use in simulators, BMC Neuroscience, 2011. https://doi.org/10.1186/1471-2202-12-S1-P80
+category:       Algebra
+homepage:       https://github.com/volr/csa#readme
+bug-reports:    https://github.com/volr/csa/issues
+author:         Jens Egholm Pedersen
+maintainer:     Jens Egholm Pedersen
+license:        GPL
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+extra-source-files:
+    CHANGELOG.md
+    LICENSE
+    package.yaml
+    README.md
+    stack.yaml
+
+source-repository head
+  type: git
+  location: https://github.com/volr/csa
+
+library
+  hs-source-dirs:
+      library
+  ghc-options: -Wall
+  build-depends:
+      base >=4.10.0 && <5
+    , hmatrix
+  exposed-modules:
+      CSA
+  other-modules:
+      Paths_csa
+  default-language: Haskell2010
+
+test-suite csa-test-suite
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs:
+      test-suite
+  ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
+  build-depends:
+      base >=4.10.0 && <5
+    , csa
+    , hedgehog
+    , hmatrix
+    , tasty
+    , tasty-hedgehog
+    , tasty-hspec
+  other-modules:
+      Paths_csa
+  default-language: Haskell2010
diff --git a/library/CSA.hs b/library/CSA.hs
new file mode 100644
--- /dev/null
+++ b/library/CSA.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE DataKinds #-}
+
+{-|
+Module: CSA
+Description: Connectivity description using connection-set algebra
+License: MIT
+Maintainer: jensegholm@protonmail.com
+Stability: experimental
+
+This module uses connection-set algebra to describe connectivity between
+two entities with a scalar ('Double') value. The library build on the concept
+of M. Djurfeldt's Connection-Set Algebar [1].
+The connection expressions can be compiled to a dependently typed
+'AdjacencyMatrix' from the "Numeric.LinearAlgebra.Static" package. Such
+a matrix can be used and exported as a regular n-dimensional vector.
+
+Usage:
+
+>>> toAdjacencyMatrix None :: L 2 2
+(matrix
+ [ 0.0, 0.0
+ , 0.0, 0.0 ] :: L 2 2)
+
+>>> toAdjacencyMatrix $ Minus (AllToAll 2) (OneToOne 1) :: L 2 2
+(matrix
+ [ 1.0, 2.0
+ , 2.0, 1.0 ] :: L 2 2)
+
+1: Mikael Djurfeldt. The Connection-set Algebra: a formalism for the
+representation of connectivity structure in neuronal network models,
+implementations in Python and C++, and their use in simulators,
+BMC Neuroscience, 2011. https://doi.org/10.1186/1471-2202-12-S1-P80
+-}
+module CSA where
+
+import GHC.TypeLits
+import Numeric.LinearAlgebra.Static
+
+-- | An adjacency matrix describing connections in a directed graph
+type AdjacencyMatrix = L
+
+-- | An expression algebra tree (AST) that describes connections
+--   between two elements
+data Expr
+  = None -- ^ An empty connection (only 0s)
+  | AllToAll ℝ -- ^ Full connectivity with the given value
+  | OneToOne ℝ -- ^ One-to-one (diagonally) connectivity
+  | Mask (ℝ -> ℝ -> ℝ) -- ^ A masked connectivity given by a function
+  | Plus Expr Expr -- ^ Addition of two connectivity expressions
+  | Minus Expr Expr -- ^ Subtraction of two connectivity expressions
+
+-- | Converts an expression to an adjacency matrix by unrolling the
+--   expression tree from left to right
+toAdjacencyMatrix
+  :: (KnownNat m, KnownNat n) => Expr -- ^ The expression to turn into a 'AdjacencyMatrix'
+  -> AdjacencyMatrix m n -- ^ The resulting adjacency matrix
+toAdjacencyMatrix expr = case expr of
+  None -> build (\_ _ -> 0)
+  Mask f -> build f
+  OneToOne v -> build (\x y -> if x == y then v else 0)
+  AllToAll v -> build (\_ _ -> v)
+  Plus left right -> (+) (toAdjacencyMatrix left) (toAdjacencyMatrix right)
+  Minus left right -> (-) (toAdjacencyMatrix left) (toAdjacencyMatrix right)
diff --git a/package.yaml b/package.yaml
new file mode 100644
--- /dev/null
+++ b/package.yaml
@@ -0,0 +1,50 @@
+# This YAML file describes your package. Stack will automatically generate a
+# Cabal file when you run `stack build`. See the hpack website for help with
+# this file: <https://github.com/sol/hpack>.
+name: csa
+version: '0.1.0'
+github: "volr/csa"
+license: GPL
+author: "Jens Egholm Pedersen"
+maintainer: "Jens Egholm Pedersen"
+synopsis: Connection-set algebra (CSA) library
+description: "Library for algebraic connection-set expressions, built on
+             M. Djurfeldt's idea of connection-set algebra [1].
+             \n\n
+             1: Mikael Djurfeldt. The Connection-set Algebra: a formalism for the
+             representation of connectivity structure in neuronal network models,
+             implementations in Python and C++, and their use in simulators,
+             BMC Neuroscience, 2011. https://doi.org/10.1186/1471-2202-12-S1-P80"
+category: Algebra
+
+extra-source-files:
+- CHANGELOG.md
+- LICENSE
+- package.yaml
+- README.md
+- stack.yaml
+
+ghc-options: -Wall
+
+library:
+  dependencies:
+  - base >= 4.10.0 && < 5
+  - hmatrix
+  source-dirs: library
+
+tests:
+  csa-test-suite:
+    source-dirs: test-suite
+    main: Main.hs
+    dependencies:
+    - base >= 4.10.0 && < 5
+    - csa
+    - hmatrix
+    - hedgehog
+    - tasty
+    - tasty-hspec
+    - tasty-hedgehog
+    ghc-options:
+    - -rtsopts
+    - -threaded
+    - -with-rtsopts=-N
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,66 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+# resolver: ghcjs-0.1.0_ghc-7.10.2
+# resolver:
+#  name: custom-snapshot
+#  location: "./custom-snapshot.yaml"
+resolver: lts-11.13
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#   extra-dep: true
+#  subdirs:
+#  - auto-update
+#  - wai
+#
+# A package marked 'extra-dep: true' will only be built if demanded by a
+# non-dependency (i.e. a user package), and its test suites and benchmarks
+# will not be run. This is useful for tweaking upstream packages.
+packages:
+- .
+# Dependency packages to be pulled from upstream that are not in the resolver
+# (e.g., acme-missiles-0.3)
+extra-deps: []
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.6"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
diff --git a/test-suite/Main.hs b/test-suite/Main.hs
new file mode 100644
--- /dev/null
+++ b/test-suite/Main.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE TypeOperators #-}
+
+-- | Tests for constructing and manipulating CSA matrices
+module Main where
+
+import GHC.TypeLits
+import qualified Numeric.LinearAlgebra.Static as LA
+
+import CSA
+
+--import Hedgehog
+--import qualified Hedgehog.Gen as Gen
+--import qualified Hedgehog.Range as Range
+import Test.Tasty
+import Test.Tasty.Hspec
+--import Test.Tasty.Hedgehog
+
+-- | Test entrypoint
+main :: IO ()
+main = do
+    unitTree <- testSpec "CSA" unitTests
+    Test.Tasty.defaultMain unitTree
+
+equal :: (KnownNat m, KnownNat n) => LA.L m n -> LA.L m n -> Bool
+equal x y = (LA.extract x) == (LA.extract y)
+
+unitTests :: Spec
+unitTests = do
+    it "Can construct an empty matrix" $
+      LA.size (toAdjacencyMatrix None :: AdjacencyMatrix 2 3) `shouldBe` (2, 3)
+    it "Can construct a one-to-one matrix" $
+      equal (toAdjacencyMatrix (OneToOne 1) :: AdjacencyMatrix 2 2) (LA.matrix [1, 0, 0, 1] :: LA.L 2 2) `shouldBe` True
+    it "Can construct a reverse one-to-one matrix" $
+      equal (toAdjacencyMatrix (Minus (AllToAll 1) (OneToOne 1))) (LA.matrix [0, 1, 1, 0] :: LA.L 2 2) `shouldBe` True
