# π-Ware – M.Sc thesis project

I just defended my M.Sc thesis, and therefore concluded the master programme “Programming Technology” at Utrecht University. Two years of hard work and the most awesome title of all was finally conferred upon me: “Master of Science” ☺

Thus it might be a good time to finally talk here about what was the subject of the thesis project: hardware design. More specifically, I developed a *library* for hardware description, simulation, synthesis and verification of circuits, and this library was embedded in the *dependently-typed* Agda programming language.

### But what does this all actually *mean*?

First of all, dependent types: in a language with dependent types, you can have types that depend on values. More specifically, the types of function arguments can depend on the *values* of other (previous) arguments. Consider, for example, a function to `take`

a prefix of a vector (`Vec`

). The type signature of `take`

in Agda might look as follows:

` take : ∀ {α m n} → Vec α (m + n) → Vec α m`

That is, given a certain amount of elements to be “taken” (`m`

), we can then **require** the *type* of the passed `Vec`

to have a length of *at least* `m`

(its length is `m + n`

, for some `n`

).

So, by using dependent types in this function, we can guarantee **at compile time** that it will **never** be passed an argument with length less than `m`

. Any attempt at a “bad” call anywhere in the program would cause a **type error** during compilation. In this way, dependent types can help to “constrain” the domain of functions, avoiding unexpected cases during runtime and preventing bugs.

### Programming is proving – Proving is programming

Another use of dependent types is to guarantee properties of the *returned value* of functions. It is known for a long time in Computer Science that a certain “duality” exists between programming language’s *type systems* and *logics*. This is often called the Curry-Howard correspondence (or isomorphism), and was reportedly mentioned for the first time by Alonzo Church in the 1930s.

The Curry-Howard correspondence states that each type system of a programming language has a corresponding logic, and so for each type corresponds a logic formula. Terms of a given type can be viewed as *proofs* of the corresponding formula.

This is all useful when we want, for example, to ensure that a function returns a value satisfying some desired property. A simple example is a function that “splits” a given vector at a given position, returning a pair of the resulting left and right parts. For this “splitting” function to be correct, the concatenation of the returned “left” and “right” parts needs to result in the original vector passed as argument. And we can indeed establish a type for `splitAt`

that returns the “pair of parts” **together with a proof** that the returned pair satisfies our definition of correctness.

` splitAt : (xs : Vec α (m + n)) → ∃₂ λ (ys : Vec α m) (zs : Vec α n) → ys ++ zs ≡ xs`

The type of `splitAt`

can be read as:

```
Given a vector (xs) of length m + n, there is a vector ys of length m
and a vector zs of length n such that ys ++ zs ≡ xs.
```

The library I developed for hardware design – called Π-Ware – uses all aforementioned features of dependently-typed programming in order to ban certain classes of design mistakes, and to provide *static guarantees* (at compile time) of circuit well-formedness.

For example, well-typed circuit models in Π-Ware can never:

- Have floating wires
- Short-circuit
- Have combinatorial loops

Furthermore, using the Curry-Howard isomorphism we can proof, in Agda itself, properties of circuits described in Π-Ware (such as functional correctness).

### TL;DR

For more details about Π-Ware you can consult the M.Sc thesis that I wrote about it ☺, available here.

Π-Ware’s GitHub repository contains the thesis report, slides about Π-Ware from the thesis defense and other presentations, as well as, of course, the full Agda source code of the library (as a git submodule under the `agda`

directory).