---------------
- Installation && Verification
---------------

1. Installing Agda
There are a few ways to install Agda, but by far the easiest is to use
cabal. Follow the instructions here:

https://github.com/agda/agda

The emacs portion is optional, especially if you only plan to run the
compiler. If you plan to use Agda to actually prove something its HIGHLY
recommended that you use emacs and get the agda-mode working.

2. Installing the standard library

i.

    Download the standard library at:

    https://github.com/agda/agda-stdlib/

    Place it in some directory, we'll assume you put it in $HOME/lib/

    Alternatively run:

        mkdir $HOME/lib/ || echo ""
        git clone https://github.com/agda/agda-stdlib/ $HOME/lib/agda-stdlib

ii.

    Now create a file at $HOME/.agda/libraries and write the follwing into it:

    YOUR_LIB_PATH/agda-stdlib/standard-library.agda-lib

    In my case this was,

    /home/USERNAME/lib/agda-stdlib/standard-library.agda-lib

    Alternatively run:

        mkdir $HOME/.agda
        touch $HOME/.agda/libraries
        echo "$HOME/lib/agda-stdlib/standard-library.agda-lib" > $HOME/.agda/libraries


3. Type checking the soundness proofs

    Go to any directory containing Soundness.agda and run:

        agda Soundness.agda

    Note the agda compiler is very memory instensive, so running something
    memory instensive such as a browser may cause it to run out resources. This
    is especially likely if it is the first time you are compiling anything
    from the standard library.


-------------
- Code Layout
-------------

There are three directories each contain a seperate type system:

    constant
    lower_bound
    upper_bound

Within each of these directories we find the following files.

    Syntax.agda

    Context.agda
    Environment.agda
    Potential.agda

    BigStep.agda
    Statics.agda

    Soundness.agda

    NatUtil.agda
    Preservation.agda

Each of these files contains a separate module. Here we provide a simple description
of each module and their contents

    --- Syntax.agda

        This module contains the definitions for the syntax of the
        language. Here is a quick description of each of the types defined:

                 - Exp:
                     This is probably the most important definition in the
                     file. It describes the syntax of the language in
                     question. Notice it is in let-normal-form.

                 - Var:
                     The type of variables to be used within expressions. In this
                     embedding we are using explicit variables rather than De Brujin
                     indices, thus the actual type of "Var"s is arbitrary.

                 - Tp:
                     The syntactic class of types.

                 - Val:
                     The type of possible values.

                 - Oper:
                     The purpose of this type is to allow us to define cost
                     metrics. For each constructor in Exp there is a
                     corresponding constructor in Oper. Cost metrics are thus
                     functions of the type "Oper → ℕ".

                 - FTp (aka Tp × ℕ × ℕ × Tp):
                     This is the syntactic class of first order types. The first
                     Tp is the input type the second is the output. The fist ℕ is
                     the input potential and the second is output.

                 - FID:
                     FID's are "function identifiers", the application operator
                     takes in a FID and Var. The FID identifies which function
                     is being applied and the Var is the argument.

                - Sig:
                     Sig's map FID's to their type and implementation.

    -- Context.agda

        Contains the implementation of typing contexts and the "fresh" proposition
        as well some lemmas pertaining to contexts.

        In our implementation contexts are defined as:

            Ctx : Set
            Ctx = List (Var × Tp)

    -- Environment.agda

        Defines environments to be functions from variables to values.

            Env = Var → Val

        It also provides a way to extend environments:

            _,_∣_ : Var → Val → Env → Env

        So if we have an environment 'Ω', a variable 'x', and a value 'V'. We could
        write:

            (x , V ∣ Ω)

        Which is a function which maps 'x' to 'V' and everything else the same as
        'Ω' does.

        Other important definitions are the well-formedness judgments. These are the
        inductive types ValOK (a value is well formed w.r.t a type) and EnvOK (a
        typing context is well formed w.r.t. to an environment).

    -- Potential.agda

        Defines the way we calculate potential for values, "pot-val", and contexts,
        "pot".

        Note that as stated in the paper we parameterize these functions with
        derivations of ValOK and EnvOK respectively. This allows us to only consider
        well formed terms in our potential implementation.

        There are also a number of useful lemmas about potential.

    -- BigStep.agda

        Defines the inductive type pertaining to operational cost semantics. An
        expression of type "Ω ⊢ E ⇓ V ∣〈 q , q' 〉" would be derivation of the
        proposition that,

            "Under environment Ω the expression E evaluates to value V with starting
            potential q and final potential q'"

    -- Statics.agda

        Defines the inductive type pertaining to typing. A term of type
        "Γ ⊢ E ∶ T ↓〈 q , q' 〉" would be a derivation of the proposition
        that,

            "Under typing context Γ expression E has the type T with starting
            potential q and final potential q'"

        Defines the "ShareOK" inductive type which describes which types are
        allowed to be "shared".

        Also defined is the subtyping relation "<∶".

        Lastly we define "SigOK Δ" which says that the function signature is
        well formed. Essentially the property is that if the signature maps a
        function identifier to a given type and implementation then there
        should be a typing derivation of the implementation with the provided type.

    -- NatUtil.agda

        Utilities for dealing with natural numbers.

    -- Preservation.agda

        A proof of preservation. This module proves that if we know
        "Γ ⊢ E ∶ T ↓〈 p , p' 〉" and " Ω ⊢ E ⇓ V ∣〈 q , q' 〉" then we know
        that "ValOK E T".


    -- Soundness.agda

        This is the most important module as it contains the soundness proof. In
        each version of this module the soundness proof is called "soundness".

        In the case of the lowerbound it is stated as:

        soundness :
                ∀ (Γ : Ctx)(Ω : Env)(ok : EnvOK Ω Γ)
                  (E : Exp)(V : Val)(T : Tp)(q q' : ℕ){p p' : ℕ}
                  (DS : Γ ⊢ E ∶ T ↓〈 q , q' 〉)
                  (DE : Ω ⊢ E ⇓ V ∣〈 p , p' 〉)
                  (sok : SigOK Δ)
                → ∀(k r : ℕ)
                  → k + (q' + pot-val (preservation DS DE ok sok)) < q + pot Γ ok + r
                  → ¬ Σ ℕ (λ k' → Ω ⊢ E ⇓ V ∣〈 k , k' 〉 × r ≤ k')

        This is saying if we know "Γ ⊢ E ∶ T ↓〈 q , q' 〉", "Ω ⊢ E ⇓ V ∣〈 p , p' 〉",
        and "SigOK Δ" then we can say that:

                ∀(k r : ℕ)
                  → k + (q' + pot-val (preservation DS DE ok sok)) < q + pot Γ ok + r
                  → ¬ Σ ℕ (λ k' → Ω ⊢ E ⇓ V ∣〈 k , k' 〉 × r ≤ k')

        As mentioned above, for "pot-val" to calculate the potential of "V" of
        type "T" we need to provide it a term of type "ValOK V T", which is
        what "preservation DS DE ok sok" returns. So here "pot-val
        (preservation DS DE ok sok)" is the type of potential resulting value
        and "pot Γ ok" is the potential of the context.
