2021-12-28 20:26:19 +03:00
|
|
|
|
module FirstMilestone;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Module declaration
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
module M; -- This creates a module called M.
|
2021-12-30 18:44:25 +03:00
|
|
|
|
end; -- This closes the current module in scope.
|
2021-12-28 20:26:19 +03:00
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-30 18:44:25 +03:00
|
|
|
|
-- Import definitions from existing modules
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
2021-12-30 18:44:25 +03:00
|
|
|
|
import Primitives;
|
|
|
|
|
|
|
|
|
|
{- The line above will import to the local scope all the
|
|
|
|
|
public names qualified in the module called
|
|
|
|
|
Primitives.
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
open Primitives;
|
|
|
|
|
|
|
|
|
|
{- The line above will import to the local scope all the
|
|
|
|
|
public names unqualified in the module called
|
|
|
|
|
Prelude.
|
|
|
|
|
-}
|
2021-12-28 20:26:19 +03:00
|
|
|
|
|
2021-12-30 18:44:25 +03:00
|
|
|
|
import Backend;
|
2021-12-28 20:26:19 +03:00
|
|
|
|
|
2021-12-30 18:44:25 +03:00
|
|
|
|
-- Additionally, one can only import unqualified names by means of
|
|
|
|
|
-- the keyword "using".
|
|
|
|
|
open Backend using { LLVM }; -- this imports to the local scope only the
|
|
|
|
|
-- variable called LLVM.
|
|
|
|
|
-- One can use ---in combination with `using`--- the keyword `hiding`
|
|
|
|
|
-- to avoid importing undesirable names.
|
2021-12-28 20:26:19 +03:00
|
|
|
|
|
2021-12-30 18:44:25 +03:00
|
|
|
|
import Prelude;
|
2022-01-11 12:14:19 +03:00
|
|
|
|
open Prelude hiding { Nat ; Unit ; Empty } ;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Inductive type declarations
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:37:06 +03:00
|
|
|
|
-- An inductive type named Empty without data constructors.
|
2021-12-28 20:26:19 +03:00
|
|
|
|
inductive Empty {};
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:37:06 +03:00
|
|
|
|
-- An inductive type named Unit with only one constructor.
|
2021-12-28 20:26:19 +03:00
|
|
|
|
inductive Unit { tt : Unit; };
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2022-01-11 12:14:19 +03:00
|
|
|
|
inductive Nat' : Type
|
2021-12-28 20:26:19 +03:00
|
|
|
|
{ zero : Nat' ;
|
|
|
|
|
suc : Nat' -> Nat' ;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
};
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- The use of the type `Type` below is optional.
|
|
|
|
|
-- The following declaration is equivalent to Nat'.
|
|
|
|
|
|
|
|
|
|
inductive Nat {
|
|
|
|
|
zero : Nat ;
|
|
|
|
|
suc : Nat -> Nat ;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
-- A term definition uses the symbol (:=) instead of the traditional
|
|
|
|
|
-- symbol (=). The symbol (===) is reserved for def. equality. The
|
2021-12-28 20:37:06 +03:00
|
|
|
|
-- symbols (=) and (==) are not reserved.
|
2021-12-28 20:26:19 +03:00
|
|
|
|
|
2021-12-28 12:36:41 +03:00
|
|
|
|
zero' : Nat;
|
2021-12-28 20:26:19 +03:00
|
|
|
|
zero' := zero;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- * Inductive type declarations with paramenters.
|
|
|
|
|
|
|
|
|
|
-- The n-point type.
|
|
|
|
|
inductive Fin (n : Nat) {
|
|
|
|
|
zero : Fin zero;
|
|
|
|
|
suc : (n : Nat) -> Fin (suc n);
|
2021-12-28 12:36:41 +03:00
|
|
|
|
};
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- The type of sized vectors.
|
|
|
|
|
inductive Vec (n : Nat) (A : Type)
|
|
|
|
|
{
|
|
|
|
|
zero : Vec Nat.zero A;
|
|
|
|
|
succ : A -> Vec n A -> Vec (Nat.succ n) A;
|
|
|
|
|
};
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:37:06 +03:00
|
|
|
|
-- * Indexed inductive type declarations.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- A very interesting data type.
|
|
|
|
|
inductive Id (A : Type) (x : A) : A -> Type
|
|
|
|
|
{
|
|
|
|
|
refl : Id A x x;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
};
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Unicode, whitespaces, newlines
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- Unicode symbols are permitted.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
ℕ : Type;
|
|
|
|
|
ℕ := Nat;
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- Whitespaces and newlines are optional. The following term
|
|
|
|
|
-- declaration is equivalent to the previous one.
|
|
|
|
|
ℕ'
|
|
|
|
|
: Type;
|
|
|
|
|
ℕ'
|
|
|
|
|
:=
|
|
|
|
|
Nat;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- Again, whitespaces are optional in declarations. For example,
|
|
|
|
|
-- `keyword nameID { content ; x := something; };` is equivalent to
|
|
|
|
|
-- `keyword nameID{content;x:=something;};`. However, we must strive
|
|
|
|
|
-- for readability and therefore, the former expression is better.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Axioms/definitions
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
axiom A : Type;
|
|
|
|
|
axiom a : A;
|
|
|
|
|
axiom a' : A;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Pattern-matching
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
f : Nat -> A;
|
|
|
|
|
f := \x -> match x -- \x or λ x to denote a lambda abstraction.
|
|
|
|
|
{
|
|
|
|
|
zero ↦ a ; -- case declaration uses the mapsto symbol or the normal arrow.
|
|
|
|
|
suc -> a' ;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
-- We can use qualified names to disambiguate names for
|
|
|
|
|
-- pattern-matching. For example, imagine the case where there are
|
|
|
|
|
-- distinct matches of the same constructor name for different
|
|
|
|
|
-- inductive types (e.g. zero in Nat and Fin), AND the function type
|
|
|
|
|
-- signature is missing.
|
|
|
|
|
|
|
|
|
|
g : Nat -> A;
|
|
|
|
|
g Nat.zero := a;
|
|
|
|
|
g (Nat.suc t) := a';
|
|
|
|
|
|
|
|
|
|
-- For pattern-matching, the symbol `_` is the wildcard pattern as in
|
|
|
|
|
-- Haskell or Agda. The following function definition is equivalent to
|
|
|
|
|
-- the former.
|
|
|
|
|
|
|
|
|
|
g' : Nat -> A;
|
|
|
|
|
g' zero := a;
|
|
|
|
|
g' _ := a';
|
|
|
|
|
|
|
|
|
|
-- Note that the function `g` will be transformed to a function equal
|
|
|
|
|
-- to the function f above in the case-tree compilation phase.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- The absurd case for patterns.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
|
|
|
|
exfalso : (A : Type) -> Empty -> A;
|
|
|
|
|
exfalso A e := match e {};
|
|
|
|
|
|
|
|
|
|
neg : Type -> Type;
|
|
|
|
|
neg := A -> Empty;
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- An equivalent type for sized vectors.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
Vec' : Nat -> Type -> Type;
|
|
|
|
|
Vec' Nat.zero A := Unit;
|
|
|
|
|
Vec' (Nat.suc n) A := A -> Vec' n A;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Fixity notation similarly as in Agda or Haskell.
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
infixl 10 + ;
|
|
|
|
|
+ : Nat → Nat → Nat ;
|
|
|
|
|
+ Nat.zero m := m;
|
|
|
|
|
+ (Nat.suc n) m := Nat.suc (n + m) ;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Quantities for variables.
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- A quantity for a variable in MiniJuvix can be either 0,1, or Any.
|
|
|
|
|
-- If the quantity n is not explicit, then it is Any.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- The type of functions that uses once its input of type A to produce a number.
|
2022-01-11 12:14:19 +03:00
|
|
|
|
axiom funs : (x :1 A) -> Nat;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
axiom B : (x :1 A) -> Type; -- B is a type family.
|
|
|
|
|
axiom em : (x :1 A) -> B;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Where
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
a-is-a : Id A a a;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
a-is-a := refl;
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
a-is-a' : Id A a a;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
a-is-a' := helper
|
|
|
|
|
where {
|
|
|
|
|
open somemodule;
|
2021-12-28 20:26:19 +03:00
|
|
|
|
helper : Id A a a;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
helper := a-is-a;
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Let
|
|
|
|
|
--------------------------------------------------------------------------------
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- `let` can appear in term and type level definitions.
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
a-is-a'' : Id A a a;
|
|
|
|
|
a-is-a'' := let { helper : Id A a a;
|
|
|
|
|
helper := a-is-a; }
|
|
|
|
|
in helper;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
a-is-a''' : let { typeId : (M : Type) -> (x : M) -> Type;
|
|
|
|
|
typeId M x := Id M x x;
|
|
|
|
|
} in typeId A a;
|
|
|
|
|
a-is-a''' := a-is-a;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
-- Debugging
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
e : Nat;
|
|
|
|
|
e : suc zero + suc zero;
|
|
|
|
|
|
|
|
|
|
two : Nat;
|
|
|
|
|
two := suc (suc zero);
|
|
|
|
|
|
|
|
|
|
e-is-two : Id Nat e two;
|
|
|
|
|
e-is-two := refl;
|
2021-12-28 12:36:41 +03:00
|
|
|
|
|
2021-12-28 20:26:19 +03:00
|
|
|
|
-- print out the internal representation for e without normalising it.
|
|
|
|
|
print e;
|
|
|
|
|
|
|
|
|
|
-- compute e and print e.
|
|
|
|
|
eval e;
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
end;
|