A SuperCompiler for Martin-Löf's Type Theory
Scala Agda Idris Haskell Coq
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


TT Lite Build Status

TT Lite is an interpreter, type-checker and supercompiler for Martin-Löf's Type Theory (TT). It is structured into two sub-projects:

  • TT Lite Core - lightweight and modular implementation of Martin-Löf's Type Theory (TT Lite was designed with supercompilation in mind)
  • TT Lite Supercompiler - a very simple supercompiler for TT Lite.

The main feature of the supercompiler is that for any transformation performed by the supercompiler a proof of correctness is provided.

The technical internals of TT Lite are described in the preprint:

The fundamental principles of our approach to certifying supercompilation are described in the following paper:

How to build / Test

TT Lite is built using SBT. You need to install SBT first from here.

$ git clone git@github.com:ilya-klyuchnikov/ttlite.git
$ cd ttlite
$ sbt
> test

TTLite contains integration tests which invoke Agda and Coq compilers for generated proofs:

> it:test

In order to run these test you should have agda and coqc executables in path.

Quick Start

There are two sub-projects:

  • core - TT Lite Core
  • sc - TT Lite SC

TTLite Core

To launch TT Core REPL, type in sbt console core/run:

> core/run

Load some definitions from examples:

TT> import examples/nat;

Try some simple computations:

TT> plus Zero Zero;

TT> plus Zero (Succ Zero);
Succ Zero

You can look into definitions by evaluating them:

TT> plus;
\ (a : Nat) -> \ (b : Nat) ->
    elim Nat (\ (c : Nat) -> Nat) b (\ (c : Nat) -> \ (d : Nat) -> Succ d) a
forall (a : Nat) (b : Nat) . Nat;

You can introduce new definitions directly in REPL:

TT> z = Zero;

TT> z;

For definitions you can optionally specify a type (type checker will check it):

TT> m : Nat; m = Succ Zero;

(In REPL a declaration with a definition should fit a single line);

You can assume a variable of a certain type (we will call it assumed variable) just by specifying its type (a variable should start with $);

TT> $n : Nat;

TT> plus $n $n;
elim Nat (\ (a : Nat) -> Nat) $n (\ (a : Nat) -> \ (b : Nat) -> Succ b) $n

Quitting REPL:

TT> quit;

Syntax and Semantics of TT

Technical details of this implementation are described in the preprint TT Lite: a supercompiler for Martin-Löf's type theory. However, the preprint just translates code of the current implementation into mathematical notation.

The proposed way to get into this project is:

  • Sketch the preprint for grasping syntax and semantics (without details).
  • Look into examples of how functions are defined (dir examples)
  • Sketch some modules (Function.scala, Nat.scala, DProduct.scala) for getting an idea how syntax and semantics are implemented.

Tutorial is on the way.

A program in TT Lite consists of the following statements:

  • id = term; - definition
  • id : term; id = term; - typed definition;
  • import "file"; - loading of definitions from file
  • $id : term; - assumption of a variable of a certain type
  • term; - just evaluating of a term;

TT Lite SC (supercompiler)

To launch TT Lite SC REPL, type in sbt console ttlite-sc/run:

> sc/run

Launching examples:

TT-SC> import examples/hosc/10;

TT Lite SC REPL introduces a new statement:

(t1, t2) = sc t;

The meaning of the new statement is that t1 is a result of transformation of a term t by the supercompiler, t2 is a proof that transformation is correct (i.e. t2 : Id A t t1 if t : A).

t1 and t2 are put in the context as terms and available for further manipulations.

Here is an example of proving the equivalence of two expressions with assumed variables (examples/hosc/10.hs):

import examples/nat;
import examples/id;

-- proof of the associativity of addition
-- plus x (plus y z) = plus (plus x y) z

$x : Nat;
$y : Nat;
$z : Nat;

e1 = (plus $x (plus $y $z));
e2 = (plus (plus $x $y) $z);
(res1, proof1) = sc e1;
(res2, proof2) = sc e2;

-- associativity of addition using combinators
-- check that t1 and t2 are supercompiled into the same expression
eq_res1_res2 : Id Nat res1 res2;
eq_res1_res2 = Refl Nat res1;
-- deriving equality
eq_e1_e2 : Id Nat e1 e2;
eq_e1_e2 = proof_by_sc Nat e1 e2 res1 proof1 proof2;

proof_by_sc is a helper function defined in examples/id.hs. In this example correctness is checked by type-checker!

You can see input and output of supercompilation (as well as a proof):

TT-SC> import examples/hosc/10;

TT-SC> e2;
    (\ (a : Nat) -> Nat)
    (\ (a : Nat) (b : Nat) -> Succ b)
    (elim Nat (\ (a : Nat) -> Nat) $y (\ (a : Nat) (b : Nat) -> Succ b) $x)

TT-SC> res2;
    (\ (a : Nat) -> Nat)
    (elim Nat (\ (a : Nat) -> Nat) $z (\ (a : Nat)  (b : Nat) -> Succ b) $y)
    (\ (a : Nat) (b : Nat) -> Succ b)

TT-SC> proof2;
elim Nat
(\ (a : Nat) -> Id Nat
        (elim Nat (\ (b : Nat) -> Nat) $z
            (\ (b : Nat) -> \ (c : Nat) -> Succ c)
            (elim Nat (\ (b : Nat) -> Nat) $y
                (\ (b : Nat) -> \ (c : Nat) -> Succ c)
        (elim Nat (\ (b : Nat) -> Nat)
            (elim Nat (\ (b : Nat) -> Nat) $z
                (\ (b : Nat) -> \ (c : Nat) -> Succ c)
            (\ (b : Nat) -> \ (c : Nat) -> Succ c)
Id Nat
(elim Nat (\ (a : Nat) -> Nat) $z (\ (a : Nat) -> \ (b : Nat) -> Succ b)
    (elim Nat (\ (a : Nat) -> Nat) $y
        (\ (a : Nat) -> \ (b : Nat) -> Succ b)
(elim Nat (\ (a : Nat) -> Nat)
    (elim Nat (\ (a : Nat) -> Nat) $z
        (\ (a : Nat) -> \ (b : Nat) -> Succ b)
    (\ (a : Nat) -> \ (b : Nat) -> Succ b)

The whole proof term is quite long (it is long since TT Lite performs normalization of terms and terms are printed in normal form). An interested person is encouraged to launch the supercompiler to see it.

Interactive development

There is no editor or IDE plugin for TT Lite yet. So the only possibility to speedup development is to make a change in a file and reload this file in REPL. For this purpose there is a special statement:

reload file;


reload examples/id;

For now, this statemenent reloads a specified file, but do not reload its dependencies.

Why *.hs ?

If you look into examples, you will notice that all of TT Lite examples are in files with extension .hs. There is a very simple reason for this: syntax of TT Lite is quite close to Haskell and GitHub performs quite good syntax coloring fot TT Lite files if they have extension .hs. That's it :)

Further reading