[@import stdlib.http.v1];
(x => y => (x_plus_y: x + y) => );
((A, x))
(f: () -> (A: *, x: A)) =>
(A, x) = (f ());
A;
id = (A: *) => (x: A) => x;
id = id (*) Int;
X = Int -> Int;
id: (A: *) -> A -> A = x => x;
X: * = 1;
pure: (M: * -> *) -> (A: *) -> (A -> M A) -> A -> M A;
Show = {
T: *;
show: T -> String;
};
show: {S: Show} -> S.T -> String;
M: {
T: *;
} = {
T = Int;
}
T A = T A
T A = T B
* -> *
X = (A: *) -> A;
M = {
T: *;
};
F = (M: { X = * }) => ();
F = (M: { T: *; x: T; show: T -> String; }) => M.show M.x;
F = ({ T: *; x: T; show: T -> String; }) -> String;
F = (M: { T: *; show: T -> String; }) => (x: M.T) => M.show x;
F = (M: { T: *; show: T -> String; }) -> M.T -> String;
F = (X: { T: * }) => X;
Pair {A} = (A, A);
id = x => x;
T = Int -> Int;
x = true;
y = x | true -> 1 | false -> 0;
User = {
id: Nat;
name: String;
};
eduardo = {
id = 0;
name = "Eduardo";
};
Monad = {
T: * -> *;
pure: {A} -> A -> T A;
};
id: (A: *) -> A -> A;
m: (A: *) -> A -> { X: * };
id x = x;
rec%map f l =
l
| [] -> []
| el :: tl -> f el :: map f tl;
X = *;
S = { A: * };
M: S = { A = Int };
((M: S) => M) ({ A = Int });
f (M: S) = ();
type_struct_id ({ A }: { A: * }) (x: A) = x;
A = Int;
B = 1;
T: * = Int;
X = {
A: *;
B: *;
X: Unify A A;
};
T = { A: * };
F = (P: { A: _ }) => P.A
m =
M = { T = Int };
F M;
M = [%graphql {
users(id: 0) {
name
email
}
}];
f = [%c {
x: for (i = 0; i <= 10; i++) {
print(i);
};
if (true) {
print("a");
} else {
print("b");
};
goto x;
}];
q = [%sql SELECT * FROM users WHERE name = "Eduardo" WHERE id = 0]
{ a; b; } = { a = 1; b = (); };
X =
M: { A: *; } = { A = Int; };
M;
X = ((M: { A: *; }) => M) { A = Int; };
X = ({ A = Int; } : { A: *; });
f = x => x;
f = ?A => A;
?M = {};
x = (a: int) => a;
add: !(x: Int, y: Int) -> Int = (x, y) => x + y;
id: ?A -> A -> A;
id: {A} -> A -> A;
pure: ?(M: Monad) -> ?A -> A -> M A;
pure: {M: Monad} -> {A} -> A -> M A;
add: Int -> Int -> Int;
incr = ?(1 + _);
incr = ?add 1;
F = (A: *) => A;
F = A => A;
M: { T: * } = { T}
F = (X: { T: * }) => X;
S = {
T: *;
};
M: { A: * } = { A :}
Show = {
T: *;
show: T -> String;
};
show {S: Show} (x: S.T) => S.show x;
({A}) = {
T = Int;
show x = Int.to_string x;
};
show 1;
show "a";
{M} = {}
User #= {
id: Nat;
name: String;
};
Id = (A: *) => A;
map: {A} -> {B} -> (A -> B) -> List A -> List B;
map: {A} -> {B} -> (A ~> B) -> List A ~> List B;
map f l =
l
| [] -> []
| el :: tl -> f el :: map f tl;
get: String -[HTTP]> String;
read_disk file =
content = perform Read ("/tmp/" ^ file);
content ^ "x";
read_disk: String -[IO]> String;
id: {A} -> A -> A;
map_read_disk: List Int -[IO]> List Int = map read_disk;
map_id: {A} -> List A -> List A = map id;
f: Int ~> Int;
// TODO: explain why this should be rejected
T = ({ X; A: * })) => X == A;
T = ({ X: *; A = X; })) => X == A;
f = (A: *) => (x: A) => x;
f = ({ A: *; x }) => (x: A);
f = T => (x: T Int) => x;
f: (T: #(Int) -> *) -> T Int -> T Int;
T: #(Int) -> *
f = T => (x: T (Int: *)) => x;
f: (T: * -> *) -> T Int -> T Int;
f = f Option;
expected:
received: {A} -> A -> A;
S = {
A: _;
X: *;
};
Id (A: *) = A;
X = Id Int
F (A: *) = A;
App {P} {R} (F: P -> R) (X: P) = F P;
// TODO: universe polymorphism to accept the following
F: (T: * -> *) -> App T Int;
F: (T: * -> *) -> T Int;
F_ (T: * -> *) = F T;
F: (T: #Int -> #String) -> T Int;
T Int = (Return T)[(Param T) := Int];
read_file: String -[ IO ]> String;
Component {Props} = Props -> DOM;
rec%map f l = l | [] -> [] | el :: tl -> map f l;
Option {A} =
| None
| Some A;
f x = x | None -> 1 | Some x -> 1;
Option {A} = {
None: Option {A};
Some: A -> Option {A};
};
{ None; Some } = Option;
None: {A} -> (| None | Some A);
Some: {A} -> A -> (| None | Some A);
f: (| A | B ) = ;
Option: (A: *) => | None | Some A;
rec%add =
| (0, y) => y
| (x, y) => add (x - 1, y + 1);
f =
| x => 1
| B => 2
for
f = a -> a;
T: (A: *) => A = (A: *) => A;
f: (
Id A = A;
Id Int
) = 1;
{} = {}
add (a, b) = a + b;
three = add (1, 2);
x = add 1;
@deriving(field)
User = {
id: Nat;
name: String;
banned: Bool;
};
eduardo = { id = 0; name = "Eduardo" };
view_name user = <span>user.name</span>;
view_name user =
{ name; banned; _ } = user;
name = banned | false -> name | true -> "_" ^ name;
<span>name</span>;
linear_id {A: &} (x: A) = x;
y = 1;
x = linear_id 1;
State = {
counter: Int;
};
x = Rc.alloc State { counter = 1; };
x = Rc.free State;
M (state: State): State =
{ counter } = state;
{ counter }
T = {
X: Option *;
A: Param X;
};
X: { T: * };
M = X;
Id (A: *) (x: A) = x;
F A B = Id B A;
X: _;
F: (P: { X: X; A: *; }) -> ();
M = {
T: *;
};
x = (1: Int);
x = ((x: Int) => x);
x: (A: *, A) = (A = Int, x = 1);
{ A; x; y; }: { A: *; x: A; y: A } = { A = Int; x = 1; y = 2; };
a = (a: Nat, b: Nat);
id: (A: *) -> A -> A;
map: {A B} -> (f: A -> B, l: List A) -> List B;
map: (f: 'A -> 'B, l: List 'A) -> List 'B;
sequence1: (A: *) -> A -> (B: *) -> B -> B;
sequence2: (A: *) -> (B: *) -> A -> B -> B;
record1: { A: *; B: *; a: A; b: B; };
record2: { A: *; a: A; B: *; b: B; };
_ -> _ ->
(P => E2) E1;
(P = E1; E2);
F (X: _) (A: *) = assert false
Monad = (
Monad: * -> *;
pure: (A: *) -> Monad A;
);
Two basic sorts, small type(sT) and type(T), where sT contain all small types that are subject to the FORGET rule that allows to introduce implicit existentials and T are all small types that are not subject to the FORGET rule.
Ideally it should also contain an explicit way to weaken T, such as T[A := *]
, T[-A]
maybe T[A: *]
.
This should allow the type system to be decidable while polymorphism still works for existential records. And I believe it to be sound as existential records are weak existential records. I'm still a bit concerned if that doesn't break in the presence of dependent products.
A: *
means A is a type(T), so (A: *) -> A -> A
is identity function and still works for modules.
T => (x: T Int)
(x: &Int) -> (&Int, &Int)
expected :: (forall a. a -> a) -> _b -> ()
received :: forall c. c -> c -> ()
expected :: (forall a. a -> a) -> _b -> ()
received :: _c -> _c -> ()
received :: (forall a. a -> a) -- _c := (forall a. a -> a)
expected :: _c
f (a: 'A) (b: 'A) = (b : {A} -> A -> A);
Id = {A} -> A -> A;
f: Link Id -> Link Id -> Link Id;
X = { A: Int; B: Int; C: Int; };
x: X = magic ();
{ A; B; C; } = x;
X = (A: Int, (B: Int, C: Int));
x: X = magic ();
A = fst X;
B = fst (snd X);
C = snd (snd X);
(A: *) -> A;
M: (A: *, (A, A -> String)) = magic ();
M: (A: *, x: A) = (A = Int; x = 1);
U = (A: *, ((A = A, A -> ())) -> ());
V = (A = U, A -> ());
V <= U;
(A = U, A -> ()) <= (A: *, ((A = A, A -> ())) -> ());
(A = U, A -> ()) <= (A: *, ((A = A, A -> ())) -> ());
Int = (#Int: ##Int);
N = (A: *) => A;
N: (A: *, #A) = (A = Int, A);
IdT = (A: *) -> #A;
f (Id: IdT) (x: Id Int) = x;
f (T: * -> *)
Id: (A: *) -> #A = (A: *) => A;
(A: *) -> *
T = (A: *, (_ = A, x: A));
T = (A: *) -> (B = A, _ : A);
x = f (Int -> Int);
T = (A: *) => (B = A, _ = A);`
x = (A = *, A);
(A: *, (x: A, y: A))
(A: *, _: (B: *, (x: A, y: B)));
(A: *, _: (B: *, (x: B, y: A)));
(B: *, _: (A: *, (x: A, y: B)));
(B: *, _: (A: *, (x: B, y: A)));
(A: *, _: (x: A, (B: *, y: B)));
(B: *, _: (x: B, (A: *, y: A)));
(A: *, _: (x: A, (B: *, y: B)));
(A: *, _: (x: A, (B: *, y: B)))
add a b = (
c = a + b;
c
);
(x: t = e1; e2);
(((x: t) => e2) (e1));
(e: t);
(((x: t) => x) e);
M = {
Y: (A: *) = (A = Int, x = one);
};
(A: *, x: A) -> A;
X = P;
m: Fst P = snd X;
(L, m) = P;
x = (m: L);
f = (A: *) => (P: (A = A, x: A)) => P;
// TODO: support this type
(f: (A: *, x: A) -> (A = A, x: A));
(f: (P: (A: *, x: A)) -> (A = Fst P, x: A));
(f: )
Ex = (A: *, x: A);
// works, one: int
one =
P: Ex = (A = Int, x = one);
snd P;
one = ((P: Ex) => snd P) (A = Int, x = one);
// fails, type would escape it's scope
fails =
P: Ex = ((A = Int, x = one): Ex);
snd P;
fails = ((P: Ex) => snd P) ((A = Int, x = one): Ex);
// fails, type would escape it's scope
fails =
P: Ex = (A = Int, x = one);
M = (A = fst P, x = snd P);
snd M;
fails = ((P: Ex) => snd P) ((A = Int, x = one): Ex);
M: (A: *, x: A) = M;
X = M;
P = X.A;
M: (A = M.A, x: A)
f = (X: Int) => (A: *, x: A);
(f 1).A
f (T: * -> *)
f (A: *) =
A
| Nat -> "nat"
| String -> "string";
f (A: &) =
A
| Nat -> "nat"
| String -> "string";
f: (Car -> ()) -> ();
f ((x: Tesla) => ());
expected :: Car -> ()
received :: Tesla -> ()
received :: Car
expected :: Tesla
expected :: ()
received :: ()
f = (M: (A: *, x: A)) -> M.A;
x = f ((A = Int, x = 1): (A: *, x: A))
(A: Int, x: A).A
_{ A: _; }
x => x.1;
x = (x = 1, y = 2)
User = (
id: Nat,
name: String,
);
eduardo = (
id = 0,
name = "a"
);
User = {
id: Nat;
name: String;
};
eduardo = {
id = 0;
name = "a";
};
f = (x: (A: Int; ..._)) => x.A;
z = f (A = 1, x = 2);
a = { (x, y) = (1, 2); };
b = { x: Nat; y: Nat; };
T = Int -> (Int, Int);
x = (Int, Int);
fst: (R: * -> *) -> (P: (L: *, r: R L)) -> P.L;
snd: (R: * -> *) -> (P: (L: *, r: R L)) -> R P.L;
F: Nat -> #Int;
Id: (A: *) -> A -> A;
x = Id ((A: *) -> #A);
// λ→
((x: Int) -> Int): *;
((A: #Int) -> Int): *;
((x: Int) -> #Int): *;
// System λω
((A: *) -> #A): * -> *;
((A: * -> *) -> #T): (* -> *) -> * -> *;
((A: * -> *) -> #(T Int)): (* -> *) -> *;
((A: #Int) -> (A: *) -> #A): _;
// System Fω
((A: *) -> A): *;
((T: * -> *) -> T A): *;
((T: * -> *) -> T): _;
(x: Int, y: Int): *;
(A: #Int, B: #Int): *;
(A: *, x: A): *;
(T: * -> *, x: T Int): *;
((A: *) -> A): *;
((T: * -> *) -> T A): *;
((A: *) -> #A): * -> *;
((T: * -> *) -> #T): (* -> *) -> * -> *;
(A: *, X: #A): (*, *);
(T: * -> *, X: #T): (* -> *, * -> *);
*;
* -> *;
Id = (A: *) => A;
make = (A: *) => (x: A) => (x = A, y = 1);
accept: (M: (X: *, Y: X)) -> M;
(X
p = f ((A: *) -> #A) Id;
p = (x = Id, y = 1);
pair: (A: *, B: A) = (A = Int, B = 1);
m =
p: (A: *, x: A) = (A = Int, x: Int);
p;
m = ((p: (A: *, x: A)) => p)
((A = Int, x: Int): (A: *, x: A));
x := 1;
T = a == b;
t = 1 === 1;
T: #Int = Int;
x <== e1;
e2
((x => e2) e1)
(x <- e1; e2)
id = (A: *) => (x: A) => x;
id = {A: *} => (x: A) => x;
id = x => x;
Monad = {
T: * -> *;
pure: A -> T A
};
pure: {M: Monad} -> {A: *} -> A -> M A;
option_int: Option Int = pure {Option} {Int} 1;
make_array: (x: Int | x >= 0) -> (A: *) -> (initial: A) -> Array A;
twice_one = ((_: gte -1 0) -> (A: *) -> (initial: A) -> Array A) ;
// m.te
// m.tei
// m.test.tei
// m.extend.tei
// untyped
((x => e2) e1) === (e2[x := e1]);
(x = e1; e2) === (e2[x := e1]);
// subtyping
(((x: s) => e2) (e1: t)) =~= (e2[x := e1]);
(x: s = (e1: t); e2) =~= (e2[x := e1]);
(m: t) == (((x: t) => x) m);
(x: t = e1; e2) == (((x: t) => e2) e1);
(x: t = e1; e2) != (x = (e1: t); e2);
F (make_m ());
p = ((A = Int, x = 1) : (A: *, x: A));
Ex = (A: *, x: A);
one =
P: Ex = (A = Int, x = one);
snd P;
one = ((P: Ex) => snd P) (A = Int, x = one);
(e : t) === (((x: t) => x) e)
{ x: Nat } <: { x: Nat; y: Nat }
(((x: { x: Nat; }) => x) (_: { x: Nat; y: Nat }))
Program =
((magic ()), (magic ()), e2));
Program =
(User: User_S = magic ();
Message: Message_S = magic ();
(User, Message, e2));
Test = ();
e = (x: Int) => x;
x1 = (e: (x: Int) -> Int);
x2 = ((z: (x: Int) -> x) => z) e;
(x := e1; e2)
(x: Nat) => (y: x == 1) => x;
n = 1;
x =
1 == n
| Eq => x
| Neq => y;
Nat = {n} -> Int | n >= 0;
((x: 1) => x) 1;
(x = e1; e2);
S (T: *) = (zero: T; succ: T -> T);
ExM (R: *) (cb: (T: *) -> S T -> R) =
cb Int (zero = 0; succ = x => x + 1);
M = ExM ();
Id = (A: *) -> (x: A) -> (x: A);
id: (A: *) -> (x: A) -> A = (A: *) => (x: A) => x;
f = (id: (A: *) => (x: A));
Bool = (R: &) => R => R => R;
(true_: Bool) R a b = a;
(false_: Bool) R a b = b;
if_true_x_else_x_concat_y (pred: Bool) (x: String) (y: String) =
pred String x (x ^ y);
Bool = (I: &) -> (O: &) -> (I -> O) -> (I -> O) -> I -> O;
(true_: Bool) I O x y a = x a;
(false_: Bool) I O x y a = y a;
(not_: Bool -> Bool) b = b Bool Bool (() => false_) (() => true_) ();
(and_: Bool -> Bool -> Bool) l r = l Bool Bool (r => r) (_r => false_) r;
(or_: Bool -> Bool -> Bool) l r = l Bool Bool (_r => true_) (r => r) r;
Bool =
if_true_x_else_x_concat_y (pred: Bool) (x: String) (y: String) =
pred String String (x => x) (x => x ^ y) x;
if_ (pred: Bool) =>
(bool: A -> B) =>
(else_: A -> B) =>
Nat: {
T: *;
} = {
T = Int;
};
Id = (L: U) => (A : * : L) => (x: A) => x;
M: {
T: *;
x: T;
} = {
S = {
name: String;;
};
x = {
name = "Eduardo";
};
};
f = (P1: (A: *; x: A)) =>
(A; x) = P1;
(A; x);
f = (P1: (A: *; (B = A; x: A)) =>
(A; (B; x)) = P1;
(A; (B; x));
S: {
T: _;
x: T;
} = {
T = Int;
x = 1;
}
x: M.T = M.x;
f = (K: ?) => (A: K) => (x: A) => x;
f: (A: *) -> (B: *) -> A -> B = assert false
LAMBDA(
DUP;
CALL;
);
DUP;
CALL;
PUSH 1;
PUSH 2;
ADD;
PUSH 1;
LAMBDA(PUSH 2; ADD);
CALL;
1 + 2
(x => x + 2) 1
⊥ = (A: *) -> A;
¬ φ === φ -> ⊥;
℘ S === S -> *;
U = (X: □) -> (℘℘X -> X) -> ℘℘X;
τ: ℘℘U -> U = (t: ℘℘U) => (X: □) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ: U -> ℘℘U = (s: U) => s U τ;
∆ = (y: U) => (p: ℘U) -> σ y p -> p (τ (σ y));
Ω: U = τ ((p: ℘U) => (x: U) -> σ x p -> p x);
- positive function, negative args
- negative function, positive args
// works
pid = (x: -) =[+]> x;
nid = (x: +) =[-]> x;
// works
pnapply = (f: -) =[+]> (x: +) =[-]> f (x: +);
npapply = (f: +) =[-]> (x: -) =[+]> f (x: -);
// rejected
ppapply = (f: -) =[+]> (x: -) =[+]> = f (x: +);
nnapply = (f: +) =[-]> (x: +) =[-]> = f (x: -);
// rejected
fix = f => f f;
apply_fix = f => apply f f;
id_fix = f => id f f;
pnfix = (x: -) =[+]> (y: +) =[-]> x y;
npfix = (x: +) =[-]> (y: -) =[+]> x y;
pfix = (f: -) =[+]> f (f: +);
nfix = (f: +) =[-]> f (f: -);
pflip: - -[+]> + = ?;
nflip: + -[-]> - = ?;
fix = f => f(f);
fix(fix)
id: (K: □) -> (A: K) -> (x: A) -> A =
(K: □) => (A: K) => (x: A) => x;
All types have polarity and no restriction on elimination, just on construction.
If arrows themselves have polarity, what is the relationship between the parameter and the return with the function?
Cases to study
Description | Conclusion |
---|---|
p. x -[p]> p | Polarity is meaningless |
p. p -[p]> x | Polarity is meaningless |
p. x -[p]> -p | ?: fix can be described |
p. p -[p]> -p | ?: fix can be described |
p. -p -[p]> x | ?: lazy fix still works |
p. -p -[p]> p | Empty, no id or apply |
p. -p -[p]> -p | ? |
Nat = (R: -p) =[p]> R =[p]> (Nat =[-p]> R) =[p]> R;
Self = R =[p]> Self =[p]> R
// -p -[p]> x
// accepted
Loop = (() -[-]> Loop) -[+]> -⊥;
fix = (f: Loop) =[-]> f (() =[-]> f);
_ = fix (self =[+]>
f = self ();
f (() =[-]> f)
);
// rejected
Loop = Loop -[p]> ⊥;
fix = (f: Loop) => f f;
// -p -[p]> x
℘ S === S -> *;
U = (X: □) -> (℘℘X -[-p]> X) -[p]> ℘℘X;
τ: ℘℘U -> U =
(t: (U -[p]> *) -[-p]> *) =[p]>
(X: □ : p) =[p]>
(f : ℘℘X -[-p]> X) =[p]>
(p : (X -[-p]> *)) =[p]>
t ((x : U) =[p]> p (f (x X f)));
σ: U -> ℘℘U = (s: U) => s U τ;
∆ = (y: U) => (p: ℘U) -> σ y p -> p (τ (σ y));
Ω: U = τ ((p: ℘U) => (x: U) -> σ x p -> p x);
// p -[p]> -p
Loop = Loop -[+]> -⊥;
fix = (f: Loop) =[+]> f f;
// -p -[p]> -p
// accepted
Loop = (() -[-]> Loop) -[+]> -⊥;
// rejected
fix = (f: Loop) =[-]> f (() =[-]> f);
// accepted
Loop = (() -[-]> Loop) -[+]> () -[-]> +⊥;
fix = (f: Loop) =[-]> f (() =[-]> f) ();
_ = fix (self =[+]> () =[-]>
f = self ();
f (() =[-]> f) ()
);
(f => f(() => f)())(self => {
const f = self();
}
// rejected
Loop = Loop -[p]> ⊥;
fix = (f: Loop) => f f;
id = (A: -p) => (x: A) =[p]> x;
apply = (A: p) => (f: A -[-p]> +⊥) =[p]> (x: A) =[-p]> f x;
Nat = (R: -p) =[p]> (() =[-p]> R) =[p]> (Nat =[-p]> R) =[p]> R;
(_ -[+]> _ -[+]> _): +;
(_ -[-]> _ -[-]> _): -;
((_ -[+]> _) -[+]> _): +;
((_ -[-]> _) -[-]> _): -;
But what if the parameter has a different polarity? Such as
((_ -[+]> _) -[-]> _): ?;
((_ -[-]> _) -[+]> _): ?;
But what if the return has different polarity? Such as
(_ -[+]> _ -[-]> _): ?;
(_ -[-]> _ -[+]> _): ?;
Description | Conclusion |
---|---|
p. (p p) | Polarity is meaningless |
p. (p -p) | ? |
Description | Conclusion |
---|---|
p. x -[p]> p | ? |
p. p -[p]> x | ? |
p. x -[p]> -p | ? |
p. p -[p]> -p | ? |
p. -p -[p]> x | ? |
p. -p -[p]> p | ? |
p. -p -[p]> -p | ? |
// (p -p); p. x -[p]> p
// in this system a function can never be inside of itself?
ALoop = BLoop -> +⊥;
BLoop = ALoop -> -⊥;
fix = (f: ALoop) => f ();
id = p => (A: p) => (x: A) => x;
x = id@+ ((A: -) -> A -> A) id@-;
apply = (A: -p) => (B: p) => (f: A -> B) => (x: A) => f x;
apply : (A: -) -> (B: +) -> (A -> B) -> A -> B;
kid = (A: -p) -> A -> (A -> ⊥) -> ⊥;
x = kid Int 1 ();
incr: +Int -> -Int;
x = apply (Int -> Int) Int incr +1;
Loop = (Unit -> Loop) -> ⊥;
fix = (f: Loop) => f (() => f);
Loop = (() -[-]> Loop) -[+]> -⊥;
Nat = R => (() => R) => (Nat => R) => R;
Inner = (X: p1) => (R: p2) -> (X -> R) -> R;
Nat = (X: p) -> (Inner X -> X) -> X;
zero = (X: p) => (cb: Inner X -> X) =>
cb (R => )
n + = -;
n - = +;
id = @{p}(A: *@{p}) -> A -> A;
apply = @{p,r}(A: *{p}) => (B: *{r}) => (f: A -> B) => (x: A) => f x;
id = (A: +) -> A -> A;
+ = { (P: -) -[+]> + };
- = { (P: +) -[-]> * };
x = R => (n: R -[+]> ('Nat -> ))
x = (f: 'F -[-]> () -[+]> () as ('F: +)) => f f
concat: String -> String -> String;
f x = x;
f 1 === 1;
++False: ? = (A: +*) -> (B: +*) -> A -> B -> B;
+-False: ? = (A: +*) -> (B: -*) -> A -> B -> B;
-+False: ? = (A: -*) -> (B: +*) -> A -> B -> B;
--False: ? = (A: -*) -> (B: -*) -> A -> B -> B;
℘ S === S -> *;
fix = (f: (F -> ⊥) -> ⊥ as F) => f f;
U = (X: +□) -> (℘℘X -> X) -> ℘℘X;
b = (X: □) => (-f : ℘℘X -> X) => (+p : ℘X) =>
(+x : U) => p (f (x X f));
℘ S === S -> *;
U = (X: □) -> (℘℘X -> X) -> ℘℘X;
τ: ℘℘U -> U = (t: ℘℘U) => (X: □) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ: U -> ℘℘U = (s: U) => s U τ;
∆ = (y: U) => (p: ℘U) -> σ y p -> p (τ (σ y));
Ω: U = τ ((p: ℘U) => (x: U) -> σ x p -> p x);
Zero.z.s => z;
S.x.z.s => s.x;
lazy.f.() => f.();
fix.f => f.(lazy.f)
AddCBV.x.y.r => x.(r.y).(B.y.r);
B.y.r.u => AddCBV.u.(S.y).r;
end: (A: *) -> ⊥;
// p. -p -[p]> x
Loop = (() -[-p]> Loop) -> ⊥;
fix f = f f;
Kid p = (A: -p) -[p]> A -> ()
// p. -p -[p]> p
Kid p = (A: -p) -> A -> ()
Nat = (R: -p) -> R -> (Nat -[-p]> R) -> (R -[-p]> ⊥) -> ⊥;
Zero = (R: p) => (z: R) => (s: _) => (k: R -> ⊥) => k z;
// p. x -[p]> p, (p -p)
Loop = Loop -> ⊥;
fix (f: Loop) = f f;
Loop = (() -> Loop) -> ⊥;
fix (f: Loop) = f (() => f);
id = (A: p) => (x: A) => x;
Kid p = (A: -p) -[p]> A -> (A -[p]> ⊥) -> ⊥;
kid = (A: -p) =[p]> (x: A) => (k: A -[p]> ⊥) => k x;
x: -Kid -> (-Kid -[p]> ⊥) -> ⊥ = +kid -Kid;
x: (-Kid -[p]> ⊥) -> ⊥ = +kid -Kid -kid;
f: (() -[-p]> -T) -[p]> T;
Nat = (R: -p) -> R -> (Nat -[-p]> R) -> (R -[-p]> ⊥) -> ⊥;
Zero = (R: p) => (z: R) => (s: _) => (k: R -> ⊥) => k z;
f n = n 0
f: (A: *) -> (A = A, x: A) -> (A = A, x: A)
X = *;
id (A: *) (x: A) =
B = A;
(x: A);
id = (A: *) => (x: A) =>
((B: (=A)) => (x: B)) A;
x =
1 == 2
| Some eq -> absurd eq
| none -> "not equal";
M: (A: *, x: A);
id: (A: *) -> A -> A;
X = id A;
((x: *) => x): ((x: *) -> *);
(((x: *) => x) String): ((x: *) -> *);
((s: ((x: *) => x) String) => s): ((s: String) -> String);
(x: (x: *) => x) => x;
((x: *) => x): (x: *) -> *;
(x: (x: *) => x) -> (x: *) -> *;
(((F: * -> *) => (x: F String) => x) ((x: *) => x));
((F: * -> *) -> F String -> F String);
(A = Int, x: A): (A = Int, x: Int);
(A = Int, x: Int): (A: *, x: A);
id = (A: *) => (x: A) => A;
expected :: (A: =Int) -> Int -> A;
received :: (A: *) -> A -> A;
received :: =Int;
expected :: *; // =Int, []
expected :: Int -> Int;
received :: Int -> Int;
expected :: (A: *, x: A);
received :: (B: *, x: B);
((x: *) => x);
X: =Int = Int;
Y: =Int = X;
x = id Int;
(A = Int, x: A);
(x: Int -> Int) => (a: x) => a;
(X: *) => X =>
((X: *) => X) Int;
(M: (X: *) -> *) => M Int;
(x)
((M: (A: *, A)) => M): ((M: (A: *, A)) -> (A = Fst M, Snd M));
(A, x) = M;
x;
add = (x, y) => x + y;
add (x, y) = x + y;
Ex = (R: *) => (F: (A: *) -> (x: A) -> R) => F Int 1;
Ex: (R: *) -> (F: (A: *) -> (x: A) -> R) -> R;
((X: *) -> (A: X) => A): (A: *) -> *;
((A: *) => A): (A: *) -> *;
(A = Int, x = 1): (A = Int, x: A)
x : (x: Int) => Int;
equal = (a, b) => a = b;
id = x =>
y = x;
print y;
z = 2;
(
print 1;
x => x = 1;
print x;
)
{
x = 1;
}
let x =
T_arrow
{
var = { Var.id = 0; name = "A" };
param = T_type;
return =
T_arrow
{
var = { Var.id = 1; name = "x" };
param = T_var { var = { Var.id = 0; name = "A" }; type_ = T_type };
return = T_var { var = { Var.id = 0; name = "A" }; type_ = T_type };
};
}
let y =
T_arrow
{
var = { Var.id = 2; name = "A" };
param = T_type;
return =
T_arrow
{
var = { Var.id = 3; name = "x" };
param = T_var { var = { Var.id = 2; name = "A" }; type_ = T_type };
return =
T_var
{
var = { Var.id = 3; name = "x" };
type_ =
T_var { var = { Var.id = 2; name = "A" }; type_ = T_type };
};
};
}
print "Hello World";
True = (A: *, B: *) => A;
True (A: *) (B: *) = A;
Int: {
Int: *;
add: Int -> Int -> Int;
} = magic ();
id = (A: *) => (x: A) => x;
x = (x: Int) => x;
(*): (Int -> Int -> Int) &
(*)(1, 2)
(Int: *)
id = A. (x: A) => x;
Id (A: *) (x: A) = x;
id = x => x;
id x = x;
(Value : Value)
(& : *)
(x = 1; x)
(((x: =1) => x) 1);
(Snd (x = 1, x));
(T: *, Eq: T == Int -> Int)
(T = Int -> Int, Eq = Refl);
M = {
T = Int;
x = (1: T);
};
x: (T: *, x: T) = (T = Int, x = (1: T));
pair = (A: *) => (B: (T: *) -> *) => (x: B A) => (T = A, x = x);
pair_int_id_one = (T = Int, x = x)
x = (T: *, x: T) => x;
build_m = (T: *) => (X: (T: *) -> *) => (x: X T) => (T = T, x = x);
build_m_int = (X: (T: *) -> *) => (x: X Int) => (T = Int, x = x);
build_m_int_id = (x: Int) => (T = Int, x = );
pair = a => b => k => k a b;
fst = pair => pair (a => b => a);
snd = pair => pair (a => b => b);
pair = (a: 'A) => (b: 'B 'A) => k => k a b;
empty = 0
[empty] = 0 + 1;
[[empty]] = 0 + 1 + 1;
[[[empty]]] = 0 + 1 + 1 + 1;
Incr = Int -> Int;
Pair = (A: *, A);
incr = ((x : Int) => x);
pair = (A = Int, 1 : A);
Either =
| Left Int
| Right String;
rec%List A =
| Nil
| Cons (A, List A);
rec%map f =
| Nil => Nil
| Cons (el, tl) => Cons (f el, map f tl);
either = Left 1;
(either | Left x => x | Right s => s);
(x : String) => x;
(x : Int) => x;
((A = Int, 1 : A): (A: *, A));
((A = Int, 1 : Int): (A: *, Int));
P = (A = Int, 1 : A);
(A, x) = P;
(T: * = Int; (1: T))
(((T: *) => (1: T)) Int);
x = 1
: Nat;
(x = 1) => x;
x: 1 = 1;
x + 1;
x : (Value : Type);
id: (x = ⊥ : Int) = (x = ⊥ : Int) => x;
f = (y = ⊥ : Int) => (x : (2, y)) => x;
z = (x = ⊥ : Int) => f 2;
z : 1 : Int = 1;
x = id z
f = (x : Int) => x;
f = (x = 1) => x;
(x = 1; x);
(((x = 1) => x) 1);
(x : Int = 1; x);
(((x : Int) => x) 1)
(x := 1) = 1;
x
(a := x, b := y) = (a = 1, b = 2);
x = 1;
x
Id: {
initial : Id;
next : Id -> Id;
} = {
};
(A: * = Int, (Int))
x : Int = 1;
(x = 1) => x;
id = (x: T) => x;
x : Car = id car;
(A: *) => (x: A) => (x: A);
choose {A} {B} (bool: Bool) (a: A) (b: B) =
bool | true -> a | false -> b;
choose : {A} -> {B} -> Bool -> A -> B -> K;
x = choose true 1 2;
x = 1;
x := 1;
(T = Int, 1 : T)
Color = Red | Green | Blue;
partial_to_int = (color : ((Red | Green) : Color)) =>
color | Red => 0 | Green => 1;
f = (color: Color) =>
color
| (Red | Green) as color => partial_to_int color
| Blue => -1
T: * = Int;
T = Int;
(T = Int, 1 : T)
Id = {}
id = (A: Prop) => (x: A) => x;
id_id = id ((A: Prop) -> A -> A)
id = {A} => (x: A) => x;
id = x => x;
id = (A: Type) => (x: A) => x;
Id = (A: Type) => A;
(T = Int, 1 : T);
//
(x: t) === (((x: t) => x) x)
(((x: t) => x) x) === x
(x: t = e1; e2) === (((x: t) => e2) e1);
M = {
T = Int;
x = 1;
};
x: M.T = 1;
Option {A} =
| Some A
| None;
User = {
id : Nat;
name : String;
};
eduardo : User = {
id = 1;
name = "Eduardo";
};
(((A: *) -> A -> A) : *);
(((A: *) => (x: A) => x) : (A: *) -> A -> A);
((pred : (A: *) -> (x: A) -> (y: A) -> A) => (x: pred Type Int Id) => x)
((A: Type) => (x: A) => (y: A) => x) one
Bool = (A: Type) -> A -> A -> A;
true: Bool = A => x => y => x;
false: Bool = A => x => y => y;
f = (pred : Bool) => (x: pred Type Bool Int) => x;
(f: Type -> Type) => (x: id Int) => (y: id Int) =
((X: *) -> X -> X) Int;
M : {
id : Nat;
name : String;
} = {
id = 0;
name = "Eduardo";
};
M : {
id : Nat;
} = M;
id = (A : Type) => (x : A) => x;
g = (m : { id : Nat; name : String; }) => f { ...; name : String } g;
g = (m : { id : Nat; name : String; }) =>
((m : { id : Nat; name : String; }) => m) g;
f = (A : Row) => (x : Red | Green | Blue | #A ) => x;
g = (x : Red | Green) => f x;
f =
(company : Bool) =>
(T : company | false => { ...; cpf : CPF } | true => { ...; cnpj: CNPJ }) =>
(person : { name : String; ...T }) => person;
f : (A: Row) -> (x : { id : Nat; ...A }) -> A = magic ();
g = (m : { id : Nat; name : String }) => m;
fix%List A =
| Nil
| Cons (A, List A);
List A =
| Nil
| Cons (A, @);
rec%Person = {
id : Nat;
name : String;
children : List Person;
};
Person = (id : Nat, (name : String, children : List @))
Bool = (A: Type) => (B: Type) => (C: Type) =>
(K: Type) -> (A === C -> K) -> (B === C -> K) -> K;
true = (A: Type) => (B: Type) => (C: Type) =>
(K: Type) => (x: A === C -> K) => (y: B === C -> K) => x refl;
Option = (A: Type) => (none: Bool, none | () => Unit | () => A);
x: Option Int = magic ();
a =
(none, value) = x;
none | () => Unit;
List A =
| Nil
| Cons (A, @);
T = Type;
Type = 1;
id = ((A: Type) => (x: A) => x) Type;
(A : Type) => A;
((A : Type) => (x : A) => (y : A) => x) Type ((A : Type) -> A) (A : Type, A)
get 1 === get 1
get 1 buf === get 1 buf
A -> B
A : Type B : Type E : Row
---------------------------
A -[E]> B
((m : A -[E0]> B ! Empty) (n : A ! E1)): Either E0 E1
(True | False | ...A)
(... | True | False)
read : Unit -[ Read ]> String;
T = | #A | #B;
x = #A
S = (T : Type, T);
x = S Int 1;
T1 : Type = | A | B | C);
R : Row = ... | B | C;
T2 : Type = | A | ...R;
R : Row = ... | A;
T : Type = ...R | ...R;
T : Type = | A#0 | A#1;
handler :
(B: Row) ->
(handler: Unit -[B]> String) ->
(A: Row) ->
(K: Type) ->
(f : Unit -[ Read | ...A ]> K ) -[...A | ...B]> K
Option = | Int | String;
Option.Int
get : Nat -> Unit -<Read | Write> String;
f () : Nat =
string = get 1 ();
length string;
get : Nat -> Unit ->
(K: Type) -> (String -> K) -> String -> K;
f () =
get 1 () Nat (string => length string)
get 1 === get 1;
get 1 () !== get 1 ();
read : Unit -<Read | Write> String;
read : Unit -[Read | Write]> String;
read : Unit -<Read><Write> String;
read : Unit -[Read][Write]> String;
f : (A: Row) -> (f: Red | ...A) -> Red | ...A;
x = f (...| Red);
x: (f: Red | Red) -> Red | Red);
| Red | Red === | Red
M: {
X : Type;
X : String;
y : X\1;
} = {
X = Int;
X = "a";
y : X = 1;
};
Effect Return =
| Read : Return = String;
E = (P : Type) => (A : Type) -> A;
f : A -[]> B;
A : Type B : Type
-------------------
A -> B
A : Type B : Type E : (t: Type) -> Type
------------------------------------------
A -[E]> B
M : A -[E1]> B ! E2 N : A ! E3
---------------------------------
M N : B ! A => E1 A | E2 A | E3
A : Type B : Type E : (t: Type) -> Type
------------------------------------------
(x : A) -[E]> B : ⊥
x : A |- e : B ! E
-------------------------------------
(x : A) => e : (x : A) -[E]> B ! ⊥
M : A -[E]> B ! | N : A ! |
--------------------------------
M N : B !
M : A -> B ! E1 N : A ! E2
--------------------------------
M N : B ! A => E1 A | E2 A
M : A -[E1]> B ! E2 N : A ! E3
---------------------------------
M N : B ! A => E1 A | E2 A | E3
raise : (E : Type -> Type) -> (R : Type) -> (eff : E R) -> R;
catch : (E : Type -> Type) ->
(handler: (R : Type) -> (eff : E R) -> R) ->
(B : Type) -> (f : Unit -[E]> B) -> B
clear : (A : Type) -> (B : Type) -> (f : A -[(R: Type) => (A : *) -> A]> B) -> B =
catch ((R: Type) => (A : *) -> A) ((R : Type) => (Absurd : E R) => Absurd R)
Ty (A : Type) =
| Int: Ty Int;
f () =
x: Int = raise Ty Int Ty.Int;
x + 1;
x = catch Ty ((R: Type) => (eff : Ty R) => eff | Int => 1) Int f;
A -[((R : Type) => | Read: R = String)]> B
id : Int -> Int;
id : (A : Type) -> A -> A;
((L : Level) -> (A : Type L) -> A -> A);
NatL = (L : Level) -> (A : Type L) -> A -> (A -> A) -> A
(x = 1;
y;)
id === ∀T. λx : T. x;
|- m : T ! x
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
Never = (A : Type) -> A;
Only_when_true = (A : Type) => (pred : Bool) => pred Type A Never;
f = (pred : Bool) => (x : Only_when_true Int pred) => x
create = (n : Int & n >= 0) => n;
n >= 0
| true = p => create (n & p)
| false p =>
map = {A} => (f : )
n >= 0 | (true, eq : n >= 0 === true) => create n
(x : Bool, x === true) = true;
x = create n;
x = f false
f : (x : Int) -> ((A : Type) => (x : A) => (y : A) => x) Type Int ((A : Type) -> (x : A) -> A)
(tagged String
(case "user" { name : String })
(case "company" { name : String })
closed) : (user : ({ name : String }) -> )
incr : (x : Int) -> Int = (x : Int) => x + 1;
id = (A : Type) => (x : A) => x;
id = ((x : Int) => x) 1;
Bool = (A : Type) -> A -> A -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
add = a => b => a + b;
incr = (x : String) => add 1 x;
When = (pred : Bool) => (A : Type) => pred Type Int Never;
f = (pred : Bool) => (x : debug (pred Type Unit Never)) => x;
x = f true 1;
Id = (A : Type) => A;
x = f false
(x : debug String) => x
IO A =
| Read : A === String;
read : (file : String) -[| Read]> String = magic ();
print : (msg : String) -[| Print]> Unit = magic ();
world_if_hello : (x : String) -[| Error]> String = (x : String) =>
x
| "Hello" => "Hello World"
| _ => raise (Error "Not Hello");
(x = read "tuturu.txt";
z = world_if_hello x;
print z)
| [%effect Read file] => "Hello"
| [%effect Error error] => "Error"
| [%effect Print x] => ()
T : Type;
E : Type -> Type;
x : T ! E
add a b = a + b;
mul a b = a * b;
check : {A} -> (x : A) -> (y : A | y === x) -> Unit;
() = check (add 1 2) 3;
x = (a : Int) => check (mul a 0) 0;
x = (a : Int) => (b : Int) => check (mul a b) (mul b a);
---------------------
Type L : Type (L + 1)
A : K B : K
------------------
((x : A) -> B) : K
A : Level B : A
---------------------
(L : A) -> B : Type (max 0 L)
((A : Type 0) -> A -> A) : Type 1
Bool = (A : Type) -> A -> A -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
Id = (A : Type) -> A -> A;
id : Id = (A : Type) => (x : A) => x;
A : Type B : Type E : Type -> Type
-------------------------------------
A -[E]> B
(E : Effect) => (f : Int -[E]> Int) => f;
e ! | === e ! |
get () ! === get ()
x = eq (get ()) (get ());
A -[ | Read: Int ]-> B
(m n : Option Int ! IO)
| None =>
! IO => (handler : Option Int)
Type L : Type (L + 1)
Id = {A} -> A -> A;
id : Id = {A} => (x : A) => x;
x = id id;
U : Type = (A : Type, (A = A, A -> ()) -> ());
V = (A = U, A -> ());
V <= U;
(A = U, A -> ()) <= U;
(A = U, A -> ()) <= U;
U = (L : Level) : Type (L + 1) => (A : Type L, (A = A, A -> ()) -> ());
V = (L : Level) : Type (L + 2) => (A = U L, A -> ());
V L <= U (L + 1);
(A = U L, A -> ()) <= U (L + 1);
(A = U L, A -> ()) <= U L;
M = {
T : Type;
x : T;
};
((L : Level) -> Type L : Type (L + 1)) : Type 1
S : Type = (T : Type, Unit);
M : S = (T = S, ());
Type 0 : Type 1
(X : Type 0) => Type 0;
Int : Type 0
((x : Int) -> Int) : Type 0
S : (L : Level) -E> Type (L + 1) : Type 1 = (T : Type, Unit);
M : S = (T = S, ());
S : (L : Level) -E> Type (L + 1) = (L : Level) => (T : Type L, Unit);
M : (L : Level) -E> S (L + 1) = (L : Level) => (T = S L, ());
S : (L : Level) -> Type L = (L : Level) => (T : Type L, Unit);
M : (L : Level) -> S L = (L : Level) => (T = S L, ());
S : Type 1 = (L : Level) -> (T : Type L, Unit);
A : Type 1 = (L : Level) -> Type L;
S : Type 1 = (T : (L : Level) -> Type L, Unit)
M = (T = (L : Level) -> S L, ());
x = (L : Level) : Ex (L + 1) => (T : (LT : Level) -> Type LT = Ex L, T)
loop : Unit ->! Unit;
soundness + strong normalizing = consistency
map : ('A -> 'B) -> List 'A -> List 'B;
id : (T : Type -> Type) -> (A : Type) -> A -> T A;
call_id (id : {A} -> A -> A) =
x = id "a";
y = id 1;
(x, y);
Id = (A : Type) => A;
f = (T1 : Type) => (T2 : Type -> Type) => (x : T2 T1) => x;
x : Int = f Int Id 1;
Id = (L : Level) => (A : Type L) => Type L;
f =
(L : Level) =>
(T1 : Type L) =>
(T2 : (L : Type) -> Type L -> Type L) =>
(x : T2 L T1) => x
Id : Type 1 = Unit A;
Const = (L : Level) => (_ : Type L) => Type L;
f = (L : Level) => (x : Type L) => x;
f =
(L : Level) =>
(F : (L : Level) -> (K : Type L) -> Type L -> ((T : Type L) -> K) -> K) =>
F ((T : Type L) => (x : T) => x)
(x : T L Int) => x;
Id : Type 1 = (L : Level) -> (A : Type L) -> A -> A;
Level : Type 1
Type : (L : Level) -> Type (L + 1)
id = (A : Type 0) => (x : A) => x;
Prop : Type 0
Set : Type 0
Level : Type 0
Level : Type 0
Type 0 : Type 1
Empty = Type 0
Int : Type 1;
String : Type 2;
F = (L : Level) => (A : Type L) => (B : Type L) => (x : A) -> B;
T : Type 1 = (L : Level : Type 1) -> Int;
Type : (L : Level) -> Type (L + 1)
S : Type 1 = (L : Level, Type L);
X : Type 1 = Level;
Id : Type 1 = (L : Level : Type 1) -> (A : Type L) -> A -> A;
id = (L : Level) => (A : Type L) => (x : A) => x;
x = id 1
Id : Type 1 = (L : Level) => L;
Id : Type 1 = (A : Type 0) -> A -> A;
Id : Type 2 = (A : Type 1) -> A -> A;
id = (A : Type 0) =>
Type : (L : Level) -> Type (L + 1);
x : R = (_ : P -> R) (_ : P);
x : Type 2 = Type 1
A : Type A_L B : Type B_L
-----------------------------------------
(x : A) -> B : Type (max A_L B_L[x := 0])
max (a + 1, a) === a + 1
max (a, b) a === max a b
x : (L : Level) -> Type (L + 1) : Type 1;
x = (L : Level) => Type L;
U = (L : Level) : Type (L + 1) => (A : Type L, (A = A, A -> ()) -> ());
V = (L : Level) : Type (L + 2) => (A = U L, A -> ());
V L <= U (L + 1);
(A = U L, A -> ()) <= U (L + 1);
(A = U L, A -> ()) <= (A : Type (L + 1), (A = A, A -> ()) -> ());
(A = U L, A -> ()) <= (A = U L, (A = A, A -> ()) -> ());
SK : (L : Level) -> Type (L + 1) = (L : Level) => (A : Type L, Unit);
S : Type 1 = (L : Level) -> SK L;
M = (L : Level) => (A = S, ());
M = (L : Level) : Type (L + 2) => (A = (A : Type L, A), ());
M : Type 2 = (A : Type 1 = (A : Type 0, A), ());
F : Type L = (A : _ : Type L) -> (_ : Type L)
S : Type L = (A : _ : Type L, _ : Type L)
F : Type = (K : Type) -> (f : (A : Type) -> A -> K) -> K;
f = (K : Type) => (f : (A : Type) -> A -> K) => f ((A : Type 0) -> (x : A) -> A) ((A : Type 0) => (x : A) => x);
F : Type 1 = (L1 : Level) -> (K : Type L1) -> (f : (L2 : Level) -> (A : Type L2) -> A -> K) -> K;
f = (L1 : Level) => (K : Type L1) => (f : (L2 : Level) -> (A : Type L2) -> A -> K) =>
f (lsucc lzero) ((A : Type 0) -> (x : A) -> A) ((A : Type 0) => (x : A) => x)
x = (L : Level) =>
f = (K : Type) => (f : (A : Type) -> A -> K) => K;
id : (A : Type) -> A -> A;
id (A : Type) (x : A) = x;
x = id Int 1;
id : {A : Type} -> A -> A;
id {A : Type} (x : A) = x;
id : 'A -> 'A;
id x = x;
x = id 1;
incr (x : Int) = x + 1;
id : forall A. A -> A;
id : forall A where A extends Object;
M : {
T = Int;
x : Int;
} = {
T = Int;
x = 1;
};
M1 : {
T : Type;
x : T;
} = M;
id : (A :> Int) -> A -> A;
uip : forall x y (a b : x = y), a = b
heteregenous : forall x1 y1 x2 y2 (a : x1 = y1) (b : x2 = y2), a = b;
ext : forall A B (f g : A -> B) -> (forall x, f x = g x) -> f = g = magic id;
S : Type = (T : Type, Unit);
M1 : S = (T = S, ());
M2 : S = (T = (typeof M1), ());
S : (L : Level) -> Type (L + 1) = (L : Level) => (T : Type L, Unit);
M1 : (L : Level) -> S (L + 1) : Type 2 = (L : Level) => (T : Type (L + 1) = S L, ());
M2 : (T : Type 2, Unit) : Type 3 = (T = (typeof M1), ());
M : (L : Level) -> ((T : Type L, Unit)) = (L : Level) => (T : Type (L + 1) = S L, ());
Int : Type
String : Type
Type : Type
id = (A : Type) => (x : A) => x;
Bool = (A : Type) -> A -> A -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
Never = (A : Type) -> A;
f = (pred : Bool) => (x : pred Type Int Never) => x;
a = f true;
a = (x : Int) => x;
b = f false;
b = (x : Never) => x;
Type 0 : Type 1
Type 1 : Type 2
Type : Kind
Id : Type = (A : Type) -> A -> A;
A : _ B : K
--------------------
(x : A) -> B : K
A : K B : K
--------------------
(x : A) -> B : K[x := 0]
Type 0 : Type 1
Type L : Type (L + 1)
Id : Type 1 = (A : Type 0) -> A -> A;
id0 = (A : Type 0) => (x : A) => x;
id1 = (A : Type 1) => (x : A) => x;
x = id1 ((A : Type 0) -> A -> A) id0;
Id : Type 1 = (L : Level) -> (A : Type L) -> A -> A;
id = (L : Level) => (A : Type L) => (x : A) => x;
id = id 1 Id id;
z = (T = Int, x : T = 1);
id = (K : Kind) => (A : K) => (x : A) => x;
x = id ((A : Type) -> A -> A);
S : Type = (T : Type, Unit);
M : S = (T = S, ());
S2 = (T : S, Unit);
M : S2 = (T = S2, ());
S : (L : Level) -> Type (L + 1) = (L : Level) => (T : Type L, Unit);
M : (L : Level) -> S (L + 1) = (L : Level) => (T = S L, ());
S2 : (L : Level) -> Type (L + 2) = (L : Level) => (T : S L, Unit);
M2 : (L : Level) -> S2 (L + 1) = (L : Level) => (T = S2 L, ());
Bool = (A : Type) -> A -> A -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
max A_L (max B_L B_L) = max A_L B_L
Never = (A : Type) -> A;
Only_when = (pred : Bool) => (A : Type) => pred | true => A | false => Never;
f = (pred : Bool) => (x : Only_when pred Int) => x;
id = (L : Level) => (A : Type L) => (x : A) => x;
Hypothesis, System U is equivalent to this system, but where levels can be recursive.
Var = String;
Level = Nat;
Kind =
| KType (level : Level)
| KLevel;
Type =
| TVar (x : Var)
| TArrow (param : Type, return : Type)
| TForall (var : Var, param : Kind, return : Type);
rec%Expr =
| EVar (x : Var)
// term abstraction
| ETAbs (var : Var, param : Type, body : Term)
| ETApp (lambda : Term, arg : Term);
// type abstraction
| EKAbs (var : Var, param : Kind, body : Term)
| EKApp (lambda : Term, arg : Type);
read : String -[IO]> String;
id : {L} -> {A : Type L} -> A -> A : Type 1;
id1 : _A -> _A : Type _L1 && _L1 : Level && _A : Type _L1
id2 : _B -> _B : Type _L2 && _L2 : Level && _B : Type _L2
_A = _B -> _B
(_B -> _B) -> _B -> _B
id = id id;
map : (Int -> Int) -> ();
id2 : _B -> _B : Type _L2 && _L2 : Level && _B : Type _L2
x = map id;
id >= Int -> Int
Id = {L} -> {A : Type L} -> A -> A
f : {A : Type | A :> Id} -> A -> A;
incr : Int -> Int;
(_A -> _A) <: Int -> Int;
x = f incr;
Rec = (G : Type -> Type) => (X : Type) -> (G X -> X) -> X;
Unit = (A : Type) -> A -> A;
unit : Unit = A => x => x;
Elim = (P : Unit -> Type) => (v : P unit) => (U : Unit) => P U
Elim = (P : Unit -> Type) -> P unit -> (U : Unit) -> P U;
f = (p : (tag : Unit, tag Type String)) => (
(tag, payload) = p;
tag String payload;
);
Tag =
(H : Type) ->
(A : Type) ->
(B : Type) ->
(R : Type) ->
((Left : H === A) -> R) ->
((Right : H === B) -> R) ->
R;
Bool = (A : )
tagged =
Status = tagged ((tag : Bool) => tag Type Int String);
to_string = (status : Status) => (
(tag, content) = status;
tag String
(_h_eq_unit => "valid")
(h_eq_string => subst h_eq_string content)
);
Bool = (R : Type) ->
bool | true =>
Nat = Rec ((X : Type) => (R : Type) -> R -> (X -> R) -> R);
Status = (valid : Bool, valid Type Unit String);
f = status = | Valid => "valid" | Invalid (reason) => reason;
f = (tag : Bool) => (value : tag Type String String) => (
tag
("valid" : tag Type String String)
(value : tag Type String String)
);
Nat = (L : Level) Rec (X => (R : Type L) -> )
Bool = (A : Type) -> A -> A -> A;
Status = (tag : Bool, pred Type Unit String);
Bool =
(H : Type) ->
(T : Type) ->
(F : Type) ->
(R : Type) ->
((H_eq_T : H === T) -> R) ->
((H_eq_F : H === F) -> R) ->
R;
Tag =
(H : Type) =>
(T : Type) =>
(F : Type) =>
(R : Type) ->
((H_eq_T : H === T) -> R) ->
((H_eq_F : H === F) -> R) ->
R;
Either = (A : Type) => (B : Type) =>
(H : Type, (tag : Tag H A B, H));
Status = (tag : Bool, tag Type Int String)
Either A B = {R : Type} -> !(Left : A -> R, Right : B -> R ) -> R;
Option A =
| None
| Some A;
Option A =
tagged [
case #None Unit;
case #Some A;
];
to_string = (string_or_int : Either String Int) =>
string_or_int
| Left = s => s;
| Right = n => Int.to_string n;
to_string = (string_or_int : Either String Int) =>
[%match string_or_int
| (#Left, (#Left, s)) => s
| (#Right, (#Right, n)) => Int.to_string n]
to_string = (string_or_int : Either String Int) =>
string_or_int
| Left (Left _) => s
| Right (Right _) => Int.to_string n]
to_string = (string_or_int : Either String Int) =>
string_or_int
| (#Left, s) => s
| (#Right, n) => Int.to_string n;
[%match (a, b) with
| (true, b) => b;
| (false, _) => false;
];
(Bool [@variant]) = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
(A : Type & P A);
(A : Type & A === Int);
(A : Nat & Gte A 0);
Level : Type 1;
Type 0 : Type 1;
Type L : Type (L + 1);
Pair A B =
(R : Type) -> ((tag : A) -> (content : B tag) -> R) -> R
f = (p : Pair Bool (tag => tag Type Int String)) =>
p
(a : Type &
p Type (tag => _ => tag Type Int String)
(tag => content => content):
f = (p : (A : Bool, tag Type Int String)) => (
(tag, content) = p;
content;
):
F = (p : (A : Bool, tag Type Int String)) -> (
(tag, content) = p;
tag Type Int String
);
Tag =
(H : Type) =>
(T : Type) =>
(F : Type) =>
(R : Type) ->
((H_eq_T : H === T) -> R) ->
((H_eq_F : H === F) -> R) ->
R;
Either = (A : Type) => (B : Type) =>
(H : Type, (tag : Tag H A B, H));
to_string = (a : Either String String) => (
(H, (tag, payload)) = tag;
tag String
(H_eq_T => subst H_eq_T _ payload)
(H_eq_F => subst H_eq_F _ payload)
);
--------------
(x : A) & B
S : Type & Equal S {
a : String;
} = {
a : String;
};
Nat : (Nat : Type & {
zero : Nat;
}) = _;
x = id Nat;
Type : Type
-> : Function
{} : Record
f = (A : Type) => (B : Type) => & B;
expected : A;
received : A & B;
(==) :
((==) : {A : Type} -> (l : A) -> (r : A) -> Type) &
({A : Ord} -> (l : A) -> (r : A) -> Option (l == r));
(>=) :
((l : Nat) -> (r : Nat) -> Type) &
((l : Nat) -> (r : Nat) -> Option (l >= r));
length : (s : String) -> Nat;
create = (len : Nat & len >= 1) => ();
x = create 4096;
g = x =>
[%match x >= 1
| Some x_gte_one => f (x & x_gte_one)
| None => ()
]
Option : (Option : _ & {
some : {A} -> Option A;
});
Nat : {
zero : Nat;
};
Nat : (Nat : _ & {
zero : Nat;
})
Nat : (Nat : _ & {
zero : Nat;
}) = _;
x : Nat = Nat.zero;
(x => x : {A} -> A -> A)
(1, 2, 3)
(z = 1, x = 2, z = 3);
f : !(x : Int) => Int;
x =
x = 1;
f (x = x);
(a : Int) -> Int
(a : Int) -> Int
((a : Int)) -> Int
((x : A & y : B), )
z = (x : Int, y : Int)
Id = (A : Type) => A;
id : Type & (A : Type) => Type;
Point : Type & (Type, Type) = (Int, Int);
x = (Int, Int)
f : Type & {A} => Type & {T} => (x : {A : T}) => T;
Id #= {A} => (x : A) => A;
Point : Type & (Type, Type) = (Int, Int);
T = {
T = Int;
};
{R} -> {S : R } -> {A : S} -> (l : A) -> (r : A) -> R
((x : Int) => x : (x : Int) => Int);
(lambda arg)
(x : Int, y : Int);
(x = 0, y = 0);
((x, y) = p; z)
(Int, Int)
(0, 0) : (Int, Int)
x : Int & String;
z : String = x;
Nat : (Nat : Type & {
zero : Nat;
}) = _;
zero : Nat = Nat.zero;
Point : Type & (Type, Type) = (Int, Int);
Point = (Int, Int);
Point : Type = (x : Int, y : Int);
f = (a : Int, b : Int) => a + b;
x = f (a = 1, b = 2);
x = f (1, 2);
(==) :
{A} -> (a : A) -> (b : A) -> Type &
{A : Eq} -> (a : A) -> (b : A) -> Option (a == b));
(>=) :
{A} -> (a : A) -> (b : A) -> Type &
{A : Ord} -> (a : A) -> (b : A) -> Option (a >= b))
f = (a : Nat & a >= 1) => ()
Nat : {
zero : Nat;
}
l : Type & Option (1 == 2) = 1 == 2;
(==) : {A : Eq} -> (a : A) -> (b : A) -> Bool;
f = (a : Nat & a == 1) => ()
z = (x : Nat) =>
x == 1
| Some x_eq_1 -> f (x & x_eq_1)
| None -> raise "x is not 1";
Nat : {
zero : Nat;
} = _;
zero : Nat = Nat.zero;
(-) :
(x : Nat) -> Int &
(a : Int) -> (b : Int) -> Int &
();
expected :: Arrow Nat Int;
received :: Arrow Int Nat;`
(==) :
{A} -> (a : A) -> (b : A) -> Type &
{A : Eq} -> (a : A) -> (b : A) -> ?(a == b));
f = (a : Int | String) => a;
f = (a : Type & Either (A == Int) (A == String)) => a;
(==) #: {A} -> (a : A) -> (b : A) -> Type;
(==) :: {A : Eq} -> (a : A) -> (b : A) -> ?(a == b);
Nat : {
zero : Type;
} = _;
T #= Int;
x := 1;
a : Int & String = (1 & "a");
a : Int | String = 1;
f = (a : A) => a;
x =
tagged String
(case );
Option =
| Some {A} (value : A) : Option A
| None {A} : Option A;
Option : (Option : Type -> Type) & {
Some : {A} -> (value : A) -> Option A;
None : {A} -> Option A;
};
Nat : (Nat : Type) & { zero : Nat } = _;
zero : Nat = Nat.zero;
some_nat : Option Nat = Option.Some Nat.zero;
Eq = (Eq : Type) & {
equal : (a : Eq) -> (b : Eq) -> Bool
};
(==) :
{A} -> (l : A) -> (r : A) -> Type &
{A : Eq} -> (l : A) -> (r : A) -> Option (l == r);
x : Type _&_ Option (l == r) = a == 1;
f = (a : Nat) => (a_eq_1 : a == 1) => ();
zero : Int = Int.zero;
id : (x : Int) -> Int = (x : Int) => x;
id = (A : Type) => (x : A) => x;
g = (a : Nat) =>
a == 1
| Some a_eq_1 -> f a a_eq_1
| None -> raise Error;
g = (a & a == 1) {
};
f = a =>
a == 1
| a_eq_1?
| () =>
Option {A} =
| Some (value : A)
| None;
Option : {A : Type} -> (Option : Type) & {
Some : (value : A) -> Option;
None : Option;
} = _;
Option : (Option : Type -> Type) & {
Some : {A : Type} -> (value : A) -> Option A;
None : {A : Type} -> Option A;
} = _;
Overloading for propositions and value.
// overloaded ==
f = (a : Nat) (a_eq_1 : a == 1) => a;
() =
a == 1
| Some a_eq_1 => f a a_eq_1
| None => raise Error
// overloaded module
Nat : {
zero : Nat;
} = _;
zero : Nat = Nat.zero;
This creates two namespaces, this allows to define things to be used both as a proposition and a value.
(==) #: {A} -> (l : A) -> (r : A) -> Type;
(==) :: {A : Ord} -> (l : A) -> (r : A) -> Option (l == r);
Nat #: Type;
Nat :: { zero : Nat };
This leads to a problem with dependent types where you may want to reference the value on the type level, so new operators are needed, but it works nicely for many cases.
While ugly, it is also quite predictable. And make it closer to a traditional ML.
This uses of subtyping to allow two values to be packed together, it acts like a pair where the unpacking may happens implicitly.
(==) :
((==) : {A} -> (l : A) -> (r : A) -> Type) &
{A : Ord} -> (l : A) -> (r : A) -> Option (l == r);
Nat : (Nat : Type) & { zero : Nat };
This leads to problems with decidability and also with function application, statements such as 1 == 2
can be interpreted as two different functions being called, this can be limited and detected in an ad hoc manner.
This is quite cute when being used, we keep the notion of a single namespace and it can be extended to things such as constrained types (a : Nat & a == 1) => a
, it acts as a dual of pairs in the presence of subtyping.
Never = (A : Type) -> A;
Id = (A : Type) -> (x : A) -> A;
Id = (A : Type) ->
Type.clone A (A1 => A2 => (x : A1) -> A2);
x = Id
Type : Type;
id = (L : Level) => (A : Type L) => (x : A) => x;
create = (A : Type) -> (x : A) -> A;
create = (x : Int : Resource) => (x_eq_0 : Eq x 0) => x;
create = (x : Rc Int) =>
(x1, x2) = clone x;
(x_eq_0 : Eq x1 0) => x2;
f = (x : Int) =>
eq x 0
| Some (x, x_eq_0) -> create x x_eq_0
| None -> raise Error
(x : Rc Int) =>
(x1, x2) = clone x;
x1 + x2;
(x : )
Not T = (A <: T) -> A;
Theta = (A <: Top) -> Not ((B <: A) -> Not B);
f = (A0 <: Theta) => (A0 <: (A1 <: A0) -> Not A1);
context = [A0 <: Theta];
received :: A0;
expected :: (A1 <: A0) -> Not A1;
context = [A0 <: Theta];
received :: (A1 <: Top) -> Not ((A2 <: A1) -> Not A2);
expected :: (A1 <: A0) -> Not A1;
context = [A0 <: Theta; A1 <: A0];
received :: Not ((A2 <: A1) -> Not A2);
expected :: Not A1;
context = [A0 <: Theta; A1 <: A0];
received :: (A2 <: Top) -> Not ((A3 <: A2) -> Not A3);
expected :: (A2 <: A1) -> Not A2;
Not T = (A <: T) -> A;
Theta = (A <: Top) -> Not ((A <: A) -> Not A);
context = [A <: Theta];
received :: A;
expected :: (A <: A) -> Not A;
// predicativity
Not T = (A <: T) -> A;
Theta : Top 1 = (A <: Top 0) -> Not ((A <: A) -> Not A);
context = [A <: Theta];
received :: A;
expected :: (A <: A) -> Not A;
context = [A <: Theta];
received :: (A <: Top 0) -> Not ((A <: A) -> Not A);
expected :: (A <: A) -> Not A; // clash
// universe polymorphism + eta
context = [A <: Theta];
received :: A;
expected :: (A <: A) -> Not A;
context = [A <: Theta];
received :: (L : Level) -> (A <: Top L) -> Not ((A <: A) -> Not A);
expected :: (A <: A) -> Not A; // eta
context = [A <: Theta];
received :: (A <: Top 1) -> Not ((A <: A) -> Not A);
expected :: (A <: A) -> Not A;
context = [A <: Theta; A <: A];
received :: Not ((A <: A) -> Not A);
expected :: Not A;
context = [A <: Theta; A <: A];
received :: A;
expected :: (A <: A) -> Not A;
Value L <: Resource L;
id = (A : Resource) => x => x;
fix%map = (f : 'A -> 'B, l : List 'A) =>
l
| [] => []
| hd :: tl =>
Either A B =
| Left (x : A)
| Right (x : B);
Either A B =
| (tag : "left", x : A)
| (tag : "right", x : B);
Tag = "left" | "right";
is_left = (s : String) -> (tag == "left") Option;
A | B <: C
A <: C && B <: C
C <: A | B
C <: A || C <: B;
A & B <: C
C <: A || C <: B
C <: A & B
C <: A && C <: B
expected :: C
received :: A & B
expected :: Nat | 1
received :: 0
expected :: String
received :: "left" | "right"
"left" | "right" <: String
Either = (A, B) =>
| Left (x : A)
| Right (x : B);
Either = (A, B) =>
| (#Left, x : A)
| (#Right, x : A);
f = (x : Either Int String) =>
x
| (#Left, x) => x + 1
| (#Right, x) => 0;
Either = (A, B) =>
| { tag : "left"; x : A; }
| { tag : "right"; x : B; };
f = (x : Either Int String) =>
x
| { tag : "left"; x}
| Neq
Person = {
id : Nat;
name : String;
gender : Gender;
};
Company = {
id : Nat;
name : String;
};
// ML like
User =
| Person (person : Person)
| Company (company : Company);
name = (user : User) =>
user
| Person person => person.name
| Company company => company.name;
// TypeScript
User =
| { tag : "person"; person : Person; }
| { tag : "company"; company : Company; };
name = (user : User) =>
user.tag == "person"
? user.person.name
: user.company.name;
// TypeScript + Pattern Matching
User =
| { tag : "person"; person : Person; }
| { tag : "company"; company : Company; };
name = (user : User) =>
user
| { tag : "person"; person } => person.name
| { tag : "company"; company } => company.name;
// TypeScript + Pairs + like
User =
| ("person", person : Person)
| ("company", company : Company);
name = (user : User) =>
user
| ("person", person) => person.name
| ("company", company) => company.name;
// TypeScript + Pairs + labels
User =
| (#Person, person : Person)
| (#Company, company : Company);
name = (user : User) =>
user
| (#Person, person) => person.name
| (#Company, company) => company.name;
// Dependent Types like
User =
(tag : "person" | "company",
payload : tag | "person" => Person | "company" => Company);
name = (user : User) =>
(tag, payload) = user;
tag
| "person" => payload.name
| "company" => payload.name;
(Nat : Type) & { zero : Nat; }
Either A B =
| Left (x : A)
| Right (x : B);
Bool = (A : Type) -> A -> A -> A;
Either A B = (tag : Bool, tag Type A B);
Either A B =
| (tag : true, A)
| (tag : false, B);
true <: Bool
f = (x : true : Type) => x;
z = (x : Bool) => x;
l = z (true : Bool);
k : Type & Bool = true;
Nat : (Nat : Type) & {
zero : Nat;
} = _;
zero : Nat = Nat.zero;
User = {
id : Nat;
name : String;
};
x : Type _&_ Bool = true;
l : Type = x;
T : Type = (Int, Int);
type T = (Int, Int);
(x : Int) |
Either A B =
| Left (x : A)
| Right (x : B);
Bool = (A : Type) -> A -> A -> A;
Either A B = (tag : Bool, x : tag Type A B);
Either A B =
| (true, x : A)
| (false, x : B);
Either A B =
(tag : Bool, x : tag ? A : B);
f = (x : Either Int String) =>
x
| ("left", x) => true
| ("right", y) => false;
x : Bool : Type = true;
x : true : Type = true;
true : Bool.Value & Bool.Resource & Type;
User = {
id : Nat;
name : String;
};
eduardo = {
id = 0;
name = "a";
};
Show = {
show : (x : Show) -> String;
};
Type
Resource
(x => x);
(x, y);
(x == y);
(x & y);
(x | y);
Nat = (Nat : Type) & { zero : Nat; }
(X : String) | Int;
(T : Type) | Eq T T;
Option = A => | Some (x : A) | None;
Option = A =>
| (#Some, A)
| (#None, Unit);
x = ("some", 1);
f = (x : Nat & x == 0) => {
z = x + 1;
};
magic = (x : A) => (a_eq_b : A == B) : B => subst eq X;
true : Bool _&_ Type;
f = (A : Type & A <: Int) => (x : A) => x;
f = z =>
z
| x => x
| y => y;
Either A B = {K} ->
(left : (x : A) -> K, right : (x : A) -> K) -> K;
f = either =>
either (
left = x => x,
right = x => x
)
(x : A & y : B)
(A & B)
Either A B #=
| ("left", x : A)
| ("right", x : B);
F := (A : Type) => #A;
X = F Int;
Y = F Int;
Option A #=
| ("some", A)
| "none";
x : _("some", 1) = ("some", 1);
rec%Tree R =
| ("var", var : String, ...R)
| ("lam", param : String, body : Tree, ...R)
| ("app", lambda : Tree, arg : Tree, ...R);
Parse_tree #= Tree (...,);
Typed_tree #= Tree (..., type : Type);
Bool #= (A : Type) -> (x : A, y : A) -> A;
true : Bool = (A : Type) => (x : A, y : A) => x;
false : Bool = (A : Type) => (x : A, y : A) => y;
T #= Int;
x : _("left", x : A) = ("left", 1);
x : Either Int String = x;
x : ("left", x : A) = x;
l : _(1, 1) = (1, 1);
Example self_app : Uexp := fun var => UAbs (var := var)
(fun x : var => UApp (var := var) (UVar (var := var) x) (UVar (var := var) x)).
(x => A => (y : A) => (A => (x : A) => (y : A) => x))
System F + Omega + Module + Inference ->
System F + Omega + Eta + Module + Inference ->
Impredicative CoC + Type : Type + Sigma + Inference ->
Erasable Universe Polymorphic CoC + Sigma + Inference ->
Erasable Universe Polymorphic CoC + Sigma + Identity + Inference ->
Erasable Universe Polymorphic CoC
+ Sigma
+ Identity
+ Inference
+ Record
+ Pattern
+ Nominal
+ Literal
+ Intersection
+ Union;
T #=
| ("left", x : Int)
| ("right", x : String);
f = (t : T) =>
t
| ("left", x) => ()
| ("right", x) => ();
Bool = (A : Type) -> (x : A) -> (y : A) -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
sequence : {A} ->> {B} ->> (x : A) ->> (y : B) ->> B = _;
sequence = {A} => (x : A) => {B} => (y : B) => _;
sequence = {A} => {B} => (x : A) => (y : B) => _;
f = x => A => (x : A);
f = id => (id 0, id "a");
f = (x) => x;
sequence = _A0 => (x : _A) => _B1 => (y : _B) => x == y;
sequence = _B => (x : _B) => _B => (y : _B) => x == y;
Id : Type -> \0 -> \1;
Id : (A : Type) -> (x : A) -> A = _;
Id : (B : Type) -> (y : B) -> B = _;
id : (A : Type) -> (x : A) -> A = _;
f_int_or_string :
(pred : Bool) -> (x : pred Type Int String) -> pred Type Int String;
l : (x : Int) -> Int = f_int_or_string true;
x : (x : Int) -> Int = _ = id Int
f = (x : _A0) => (x : Type) => (x : A1)
id : (A : Type) -> A -> A;
(x : _p) -> \0 -> \1
(A : Type) -> -> A;
_p = Type
x\0
A\x
_r = x
((x : _p) -> _r) (Int : _p)
occurs _A0 _B1
f = x => (A : Type) => (x : A)
y = (B : Bool) => (x : B) => x
((a, b) = p; (b : A)) : ((a, b) = p; A)
((x : _A) => x + 1) : (x : Int) -> Int;
Prop : Type 0
Bool : Prop = (A : Prop) -> A -> A -> A;
f = (pred : Bool) => (x : pred Prop Bool String) => x;
f1 = p => (
((A, x) = p; ) : ((A, _) = p; A)
);
f2 = p => (
(A, x) = p;
x
);
((x : T) => e1)
(A:level):index
(_A:level):index
((A:level):offset):index
id:
(_HOLE\current)\was\distance
(A : Type) -> _C -> () -> (A\1 -> A\2) -> _C;
(X : Type) -> _C -> () -> _B\2\2\0 -> _B\2\2\2;
(X : Type) -> _C -> () -> (A\1 -> A\2)\2\2\0 -> (A\1 -> A\2)\2\2\1 -> (A\1 -> A\2)\2\2\2;
(X : Type) -> _C -> () -> (A\1 -> A\2)\2\2\0 -> (A\1 -> A\2)\2\2\1 -> (A\1 -> A\2)\2\2\2;
(_C\1\1)\0 -> A\1 -> (_C\1\1)\3;
(_C\1\1)\0 -> (_B\2\2)\0 -> (_B\2\2)\1
(_C\1\1)\0 -> A\1 -> (_C\1\1)\3;
(_C\1\1)\0 -> ((A\1)\1\2)\0 -> ((A\1)\2\2)\1;
(((A\1)\1\2)\1\1)\0 -> A\1 -> (((A\1)\1\2)\1\1)\3;
(((A\1)\1\2)\1\1)\0 -> ((A\1)\1\2)\0 -> ((A\1)\1\2)\1;
A\0 -> A\1 -> (A\3)\3;
A\0 -> A\1 -> ((A\1)\1\2)\1;
(x\0) => (y\1) => (x\1)
(_C\1)\0 -> A\1 -> (_C\1)\3;
(_C\1)\0 -> (_B\2) -> (_B\2);
(A : Type) -> A
(B : Type) -> B
A = 0
B = 0
_A = Var
(T)\offset = Link
(x : _A) => (y : _B) => (x : _B\1 -> _B\1);
_A : 0
_B : 1
expected : _A : 2
received : _B\1 -> _B\1 : 0
_A := (_B\1 -> _B\1) : 0
hole : _A
hole_offset : 2
in_offset : 0
in_: _B\1
hole : _A
hole_offset : 2
in_offset : 1
in_: _B\0
_B\1 = hole_offset - in_offset
H := T\(T_offset - H_offset + level H - min_level T)
_B\0 := _A\(2 - 0)\0
(A : Type) -> _A -> (A\2 -> A\3) -> _A\2;
(X : Type) -> _C -> _B -> _B\1;
(A : Type) -> _A -> (A\2 -> A\3) -> _A\2;
(X : Type) -> _A -> _B -> _B\1;
(A : Type) -> _A -> (A\2 -> A\3) -> _A\2;
(X : Type) -> _A -> (A\2 -> A\3) -> (A\2 -> A\3)\1;
(A : Type) -> _A -> (A\2 -> A\3) -> _A\2;
(X : Type) -> _A -> (A\2 -> A\3) -> (A\2 -> A\3)\1;
(A : Type) => (x : A\1) => x;
(A : Type) -> (x : A\1) -> A\2;
(x : _X) => (A : Type) => (x : A)
_X : 0
expected : A\1 : 0
received : _X : 2
expected_offset : 0
expected : _A\2
received_offset : 0
received : (A\2 -> A\3)\1
expected_offset : 2
expected : _A
received_offset : 0
received : (A\2 -> A\3)\1
expected : _A -> _A\1
received : _B -> (_C -> _C)
expected : _A -> _A\1
received : _A -> (_C -> _C\1)
_A := (_C -> _C\1)
_A := (A\2 -> A\3)\1\-2
_A\2 := (A\1 -> A\2)\1;
_A := (A\1 -> A\2)(1 - 2)
L = 1
H = 1
M = 0
-1 = (L)
A : Type B : Type
------------------
A | B
C <: A || C <: B
----------------
C <: A | B
A <: C B <: C
----------------
A | B <: C
Either A B =
| (tag : "left", x : A)
| (tag : "right", x : B);
(tag : "left", x : A) | (tag : "right", x : B) <: (tag : _A, x : _B);
(tag : "left", x : A) <: (tag : _A, x : _B); _A = "left" :: _B = tag | "left" => A;
(tag : "right", x : B) <: (tag : _A, x : _B); _A = "right" :: _B = tag | "right" => B;
(tag : "left" | "right", x : tag | "left" => A | "right" => B)
Bool =
(H : Type) =>
(A : Type) =>
(B : Type) =>
(K : Type) ->
((K_eq_A : H == A) => K) ->
((K_eq_B : H == B) => K) -> K;
true : A -> B -> Bool A A B = A => B => K => true => false => true (Refl A);
false : A -> B -> Bool B A B = A => B => K => true => false => false (Refl B);
Either A B =
| (tag : true, x : A)
| (tag : false, x : B);
(tag : Bool, x : Bool) | (tag : Int, x : Int);
(tag : Bool | Int, x : typeof tag | Bool => )
(H : Type, H_eq_Bool_or_Int : H == Bool | H == Int, tag : H, x : H)
f = (either : Either Int String) => (
(tag, x) = either;
()
);
(A, x) => p
0 => 1 => 2
x => (A : Type) => (x : \0)
a : (A : Type) -> _C@0 -> (A@2 -> A@3) -> _C@0\2;
b : (X : Type) -> _D@0 -> _B@0 -> _B@0\1;
a : (A : Type) -> _C@0 -> (A@2 -> A@3) -> _C@0\2;
b : (X : Type) -> _C@0\0 -> _B@0 -> _B@0\1;
a : (A : Type) -> _C@0 -> (A@2 -> A@3) -> _C@0\2;
b : (X : Type) -> _C@0\0 -> (A@2 -> A@3)\0 -> (A@2 -> A@3)\0\1;
// the fancy step
a : 0 : _C@0\2
b : 0 : (A@2 -> A@3)\0\1
a : 2 : _C@0
b : 0 : (A@2 -> A@3)\0\1
_C := (A@2 -> A@3)\0\1\(in_off - h_off)
_C := (A@2 -> A@3)\0\1\-2
// done
a : (A : Type) -> (A@2 -> A@3)\0\1\-2 -> (A@2 -> A@3) -> (A@2 -> A@3)\0\1\-2\2;
b : (X : Type) -> (A@2 -> A@3)\0\1\-2\0 -> (A@2 -> A@3)\0 -> (A@2 -> A@3)\0\1;
// meta step, just solve the offsets
a : (A : Type) -> (A@2 -> A@3)\-1 -> (A@2 -> A@3) -> (A@2 -> A@3)\1;
b : (X : Type) -> (A@2 -> A@3)\-1 -> (A@2 -> A@3)\0 -> (A@2 -> A@3)\1;
// meta step, just expand the types
a : (A : Type) -> (A@1 -> A@2) -> (A@2 -> A@3) -> (A@3 -> A@4);
b : (X : Type) -> (A@1 -> A@2) -> (A@2 -> A@3) -> (A@3 -> A@4);
// meta step, just fix the names
a : (A : Type) -> (A@1 -> A@2) -> (A@2 -> A@3) -> (A@3 -> A@4);
b : (X : Type) -> (X@1 -> X@2) -> (X@2 -> X@3) -> (X@3 -> X@4);
(f => (self => f (self self)) (self => f (self self))) id
(. (. \2 (\1 \1)) (. \2 (\1 \1))) (\. \1) : []
(. \2 (\1 \1)) (. \2 (\1 \1)) : (\. \1) :: []
\2 (\1 \1) : (. \2 (\1 \1)) :: (\. \1) :: []
(\. \1) ((. \2 (\1 \1)) (. \2 (\1 \1))) : (. \2 (\1 \1)) :: (\. \1) :: []
\1 : ((. \2 (\1 \1)) (. \2 (\1 \1))) :: (. \2 (\1 \1)) :: (\. \1) :: []
(. \2 (\1 \1)) (. \2 (\1 \1)) : ((. \2 (\1 \1)) (. \2 (\1 \1))) :: (. \2 (\1 \1)) :: (\. \1) :: []
\2 (\1 \1) : (. \2 (\1 \1)) :: ((. \2 (\1 \1)) (. \2 (\1 \1))) :: (. \2 (\1 \1)) :: (\. \1) :: []
((. \2 (\1 \1)) (. \2 (\1 \1))) ((. \2 (\1 \1)) (. \2 (\1 \1))) : (. \2 (\1 \1)) :: ((. \2 (\1 \1)) (. \2 (\1 \1))) :: (. \2 (\1 \1)) :: (\. \1) :: []
(. \2 (\1 \1)) (. \2 (\1 \1)) : ((. \2 (\1 \1)) (. \2 (\1 \1))) :: (. \2 (\1 \1))
(.\1z \1) (.\1 \1) : []
(\1 \1) : [1 -> (.\1 \1)]
(.\1 \1) (.\1 \1) : [1 -> (.\1 \1);]
(f => f f) (f => f f) : []
(f => f f) (f => f f) : [f -> f => f f]
(. \1 \2) : \2
{
x : Int;
x = 1;
}
M : {
call_id : ((A : Type) -> A -> A) -> (x : Int, y : String);
} = {
call_id = (id : (A : Type) -> A -> A) => x => id x;
call_id = id => (x = id 1, id "a")
};
f : (p : (A : Type, x : A)) -> ((A, x) = p; A);
f = (p : (A : Type, x : A)) => (
(A, x) = p;
x
);
f : (A : Type, x : A) -> A;
f = (A : Type, x : A) => x;
((x : Type) => x\1) ((A : Type\1) -> A\1)
((x : Type\1) -> Type\2) Type\1
x\1[x\1 := ((A : Type) -> A\1)]
((x : Int) => e2) e1;
x = 1;
x
((A : Type\1) => (x : A\1) => x\1) Type\1
(A : Type\1) -> (x : A\1) -> A\2
((x : A\1) -> A\2)[A := Type\1]
((x : Type\1) -> A\2)[A := Type\1]
_A -> _B
A\1 -> A\2
Type : ()
Type L : Type (L : 1)
Fix : (Fix : Type) & (fix : Fix) -> Unit;
Fix : (Fix : Type, f : (fix : Fix) -> Unit);
List :
(A : Type) ->
(L : Type) & (
| (tag : "nil")
| (tag : "cons", el : A, next : L)
);
((A : Type) -> Int\2 -> A\2 -> A\3) Int\1;
((Int\2 -> A\2 -> A\3)\-1)[A := Int\1];
(Int\1 -> A\1 -> A\2)[A := Int\1];
(Int\1 -> Int\1\1 -> Int\1\2);
(Int\1 -> Int\2 -> Int\3);
l : (x : A) -> B a : A
------------------------
l a : ((x : A) => B) a
l : (x : A) -> (y : B) -> C a : A b : B
----------------------------------------------
(l a) b : C\-1[x := a]\-1[y := B]
((A : Type\1) => A\1) Type\1
((A : Type) => A\1 -> A\2) String;
((A : Type\1) => (x : A\1) => x) : ((A : Type\1) -> (x : A\1) -> A\2)
(((A : Type\1) -> (x : A\1) -> A\2) Type\1)
((x : A\1) -> A\2); [A := Type\1]
((x : A\0) -> A\1); [A := Type\1]
((x : Type\1\0) -> Type\1\1); [A := Type\1]
(A : Type) => () => A;
(A : Type\1 : Type\0) => () => () => A; depth = 0;
(A : Type\1 : Type\1) => () => () => A; depth = 0; offset = 1;
(A : Type\1 : Type\1) => () => () => A; depth = 1;
(A : Type\1 : Type\1) => () => () => A; depth = 2;
(A : Type\1 : Type\1) => () => () => (A\3 : Type\1); depth = 3;
(A : Type\1 : Type\1) => () => () => (A\3 : Type\4); depth = 3; offset = 3;
is_bound_var = var <= depth;
(A : Type) => (x : A) => x;
(A : Type\1 : Type\0) => (x : A) => x; depth = 0;
(A : Type\1 : Type\1) => (x : A) => x; depth = 0; offset = 1;
(A : Type\1 : Type\1) => (x : A\1 : Type\2) => x; depth = 1;
(A : Type\1 : Type\1) => (x : A\1 : Type\2) => (x\1 : A\1); depth = 2;
(A : Type\1 : Type\1) => (x : A\1 : Type\2) => (x\1 : A\2); depth = 2; offset = 1;
+1
1 <= 0 = false
1 <= 1 = true
2 <= 1 = false
1 <= 2 = true
2 <= 2 = true
(A : Type\1 : Type\1) => (x : A\1 : Type\2) => (x\1 : A\2);
(A : Type\2 : Type\2) => (x : A\1 : Type\2) => (x\1 : A\2); depth = 0;
(A : Type\2 : Type\2) => (x : A\1 : Type\2) => (x\1 : A\2); depth = 0;
(A : Type\2 : Type\2) => (x : A\1 : Type\2) => (x\1 : A\2); depth = 1;
(A : Type\1 : Type\1) => () => () => (A\3 : Type\4); depth = 0;
(A : Type\1 : Type\2) => () => () => (A\3 : Type\4); depth = 0; depth < var
(A : Type\1 : Type\2) => () => () => (A\3 : Type\4); depth = 1;
(A : Type\1 : Type\2) => () => () => (A\3 : Type\4); depth = 2;
(A : Type\1 : Type\2) => () => () => (A\3 : Type\4); depth = 3;
(A : Type\1 : Type\2) => () => () => (A\3 : Type\5); depth = 3; 4 > depth
+1
(A : Type\1 : Type\1) => (A : Type\2); depth = 0;
(A : Type\1 : Type\1) => (A : Type\2); depth = 0;
Type\0 : Type\0
depth = 0; var = 1 - 1;
0 `bound` 0 = false
a `bound` a = false
var < depth
read : String -> Monad String;
debug : {A} -> A -> A;
Type : (l : Level) -> Type (l + 1);
Type 0 : Type 1;
(x : Int, y : Int) => x + y;
(p : (x : Int, y : Int)) => (
(x, y) = p;
x + y
);
((x = v; r) ((x => r) v);
((x : Int, y : Int) => x + y) (x = 1; y = 2);
(x : Int, y : Int) -> Int;
l : (x : A) -> B a : A
-------------------------
l a : B[x := A]
(x = 1, y = 1) (left => right => );
return = x => x;
add = (x, y) => (
z = x + y;
return z;
);
((x, y : Int) => x + y) == ((x : Int, y) => x + y);
((x, y : Int) => y) != ((x, y : String) => y)
(\x: IO () -> Int) (print "foobar")
Type =
| Type
| Forall (param : String) (annot : Type) (return : Type)
| Lambda (param : String) (annot : Type) (return : Term)
| Apply (lambda : Term) (arg : Term)
| Inter (var : String) (left : Type) (right : Type)
| Equal (a : Type) (b : Type);
Term =
| Var (name : String)
| Lambda (param : String) (annot : Type) (return : Term)
| Apply (lambda : Term) (arg : Term);
-----------
Type : Type
A : Type B : Type
----------------------
((x : A) -> B) : Type
A : Type B : Type e : B
-----------------------------
((x : A) => e) : (x : A) -> B
Id : Type = (A : Type) -> (x : A) -> A;
id : Id = (A : Type) => (x : A) => x;
Bool = (A : Type) -> (x : A) -> (y : A) -> A;
true = (A : Type) => (x : A) => (y : A) => x;
false = (A : Type) => (x : A) => (y : A) => y;
x : Int & String = _;
z : Int = x;
Connection : Resource = _;
send : (conn: Connection) -> (x : String) -> IO ((), Connection) = _;
close : (conn : Connection) -> IO () = _
alloc : (A : Resource) -> A;
free : (A : Resource) -> (x : A) -> ();
f = (conn0 : Connection) => (
((), conn1) = send(conn0, "Hello")?;
((), conn2) = send(conn1, "World")?;
close conn2;
);
CNat : Type = X .-> X -> (X -> X) -> X;
cZ : CNat = X .=> z => s => z;
cS : CNat -> CNat = x => X .=> z => s => s (x X z s);
Inductive : CNat -> Type =
(x : CNat) =>
(P : CNat -> Type) .->
P cZ -> ((y: CNat) .-> P y -> P (cS y)) ->
P x;
iZ : Inductive cZ = P .=> z => s => z;
iS : (x : CNat) .-> Inductive x -> Inductive (cS x) =
x .=> p => P .=> z => s => s x (p P z s)
Nat : Type = (x : CNat) & Inductive x;
Z : Nat = (x = cZ & iZ);
S : Nat -> Nat = n => (x = cS n.1, iS x n.2);
refl : {A} -> A == A = x => x;
C_bool = A. A -> A -> A;
c_true : C_bool = t => f => t;
c_false : C_bool = t => f => f;
Ind_bool : C_bool -> Type =
b => (P : Bool). P c_true -> P c_false -> P b;
ind_true : Ind_bool c_true = t => f => t;
ind_false : Ind_bool c_false = t => f => f;
Bool : Type = (b : C_bool) & Ind_bool b;
true : Bool = (b = c_true & ind_true);
false : Bool = (b = c_false & ind_false);
ind_bool : (b : Bool) -> {P} -> P true -> P false -> P b =
b => {P} => t => f =>
@b.2
(x => {X} -> ((m : Bool) -> x == m.1 -> P m -> X) -> X)
({X} => c => c true refl t)
({X} => c => c false refl f);
(m => (e : b.1 == m.1) => (u : P m) =>
e : b == m = e; // injective
u[m := b | e]
);
match_bool_with_eq :
{A} -> (b : Bool) ->
(t : (b == true) -> A) ->
(f : (b == false) -> A) -> A =
{A} => b =>
@ind_bool b
(m =>
(t : (m == true) -> A) ->
(f : (m == false) -> A) -> A)
(t => f => t refl)
(t => f => f refl);
simple_dependent_elimination = (tag : Bool) => (payload : tag Type Int String) => (
@ind_bool tag
(tag => (payload : tag Type Int String) -> String)
(payload => Int.to_string payload)
(payload => payload);
payload
);
refl : {A} -> A == A = x => x;
C_bool = A. A -> A -> A;
Ind_bool : C_bool -> Type =
b => P. P c_true -> P c_false -> P b;
Bool : Type = (b : C_bool) & Ind_bool b;
true : Bool = t => f => t;
false : Bool = t => f => f;
(b : Bool) -> {P} -> P true -> P false -> P b
C_eq = A. A -> A;
c_refl : C_eq = x => x
Ind_eq : C_eq -> Type =
eq => P. P c_refl -> P eq;
ind_refl : Ind_eq c_refl = x => x;
Eq = (eq : C_eq) & Ind_eq eq;
refl = (eq = c_refl) & ind_refl;
ind_bool : (b : Bool) -> {P} -> P true -> P false -> P b =
b => {P} => t => f => (
(m : Bool, x_eq_m_1 : b == m.1, p_m : P m) =
@b.2 (true, refl, t) (false refl f);
e : b == m = e; // injective
u[m := b | e]
);
Eq = {
&A : Type;
eq : (x : A) -> (y : A) -> x == y;
};
( == ) :
(( == ) : {A} -> (x : A) -> (y : A) -> Type) &
(( == ) : {A : Eq} -> (x : A) -> (y : A) -> x == y);
( == ) =
A. (x : A) => (y : A) => R.
{r_either_type_or_eq :
Either
(R == Type)
(_ : R == Option (x == y), cmp : (x : A) -> (y : A) -> Option (x == y))
} => (
r_either_type_or_eq
| ("left", r_eq_type) => (x == y : R)
| ("right", (r_eq_opt_x_eq_y, cmp) => (cmp x y : R))
);
x : R.
{r_either_type_or_eq :
Either
(R == Type)
(_ : R == Option (x == y), cmp : (x : A) -> (y : A) -> Option (x == y))
} -> R = 1 == 1;
f : A. (x : A) -> (y : A) ->
{r_either_type_or_eq :
Either
(Type == Type)
(_ : Type == Option (x == y), cmp : (x : A) -> (y : A) -> Option (x == y))
} -> Type;
True = (A : Type) -> A -> A;
False = (A : Type) -> A;
C_bool = A. A -> A -> A;
c_true : C_bool = t => f => t;
c_false : C_bool = t => f => f;
Ind_bool : C_bool -> Type =
b => (P : Bool). P c_true -> P c_false -> P b;
ind_true : Ind_bool c_true = t => f => t;
ind_false : Ind_bool c_false = t => f => f;
Bool : Type = (b : C_bool) & Ind_bool b;
true : Bool = (b = c_true & ind_true);
false : Bool = (b = c_false & ind_false);
f : ((x : Int) -> Int) & ((x : String) -> String) = x => x;
ind_bool : (b : Bool) -> {P} -> P true -> P false -> P b = _;
ind_eq : A. (x : A) -> (y : A) -> (eq : Eq x y) -> P. P x -> P y = _;
f = (eq : true == false) : False => (
t : (b =>
ind_bool b
(_ => Type)
True
False
) true = x => x;
f : (b =>
ind_bool false
(_ => Type)
True
False
) false = (t : _[true := false | eq]);
f
);
Either A B =
(left : Bool, payload : left A B);
match_bool_with_eq :
{A} -> (b : Bool) ->
(t : (b == true) -> A) ->
(f : (b == false) -> A) -> A =
{A} => b =>
@ind_bool b
(m =>
(t : (m == true) -> A) ->
(f : (m == false) -> A) -> A)
(t => f => t refl)
(t => f => f refl);
f = (x : Either Int String) => (
(left, payload : left Int String) = x;
match_bool_with_eq left
(left_eq_true => Int.to_string (payload : _[left := true | left_eq_true]))
(left_eq_false => (payload : _[left := false | left_eq_false]))
);
make : (x : Nat) -> (x_gt_z : x >= 0) -> _ = _
make : (x : Nat, {x >= 0}) -> _ = _
Either A B =
| (tag : "left", payload : A)
| (tag : "right", payload : B);
'A = (
f = (x : 'A) => x;
x : 'A = 1;
int
)
a : (A : Type) -> _C -> (A\2 -> A\2) -> _C\2
b : (X : Type) -> _D -> _B -> _B\1
a : (A : Type) -> _C -> (A\2 -> A\2) -> _C\2
b : (X : Type) -> _C -> _B -> _B\1
a : (A : Type) -> _C -> (A\2 -> A\2) -> _C\2
b : (X : Type) -> _C -> (A\2 -> A\2) -> (A\2 -> A\2)\1
a : (A : Type) -> _C -> (A\2 -> A\2) -> _C\2
b : (X : Type) -> _C -> (A\2 -> A\2) -> (A\2 -> A\2)\1
a : 0 : _C\2
b : 0 : (A\2 -> A\2)\1
a : 2 : _C
b : 1 : (A\2 -> A\2)
_C := (A\2 -> A\2)\-1;
a : (A : Type) -> (A\2 -> A\2)\-1 -> (A\2 -> A\2) -> (A\2 -> A\2)\-1\2
b : (X : Type) -> (A\2 -> A\2)\-1 -> (A\2 -> A\2) -> (A\2 -> A\2)\1
a : _A -> _A\1 -> _B
b : _C -> (_D -> _D\1) -> _D\1
a : _A -> _A\1 -> _B
b : _A -> (_D -> _D\1) -> _D\1
a : _A\1
b : (_D -> _D\1)
a : 1 : _A
b : 0 : (_D -> _D\1)
1 - 0
0 < 1
_D := _E\1
_A := (_E\1 -> _E\1\1)\-1
a : (_E\1 -> _E\1\1)\-1 -> (_E\1 -> _E\1\1)\-1\1 -> _B
b : (_E\1 -> _E\1\1)\-1 -> (_E\1 -> _E\1\1) -> _E\1\1
a : (_E -> _E\1) -> (_E\1 -> _E\2) -> _E\2
b : (_E -> _E\1) -> (_E\1 -> _E\2) -> _E\2
(Bool, true, false, ind_bool) = (
Bool = A. A -> A -> A;
true : Bool = t => f => t;
false : Bool = t => f => f;
Bool = (b : Bool) & (P. P true -> P false -> P b);
true : Bool = t => f => t;
false : Bool = t => f => t;
ind_bool : (b : Bool) -> P -> P true -> P false -> P b =
b => P => p_t => p_f => (
(m, b_eq_m, p_m) =
b
(x => (m : Bool, x_eq_m1 : x == m, p_m : P m))
(true, refl, p_t)
(false, refl, p_t);
(p_m : _[m := b | b_eq_m]);
);
(Bool, true, false, ind_bool);
);
Either A B =
| (tag = true, payload : A)
| (tag = false, payload : B);
(tag = true, payload : A) <: (tag : Bool, payload : tag A B)
(tag = false, payload : B) <: (tag : Bool, payload : tag A B)
f = (x : Either Int String) => (
(tag, payload : tag Int String) = x;
ind_bool
((payload : Int) => Int.to_string payload)
((payload : String) => payload)
payload
);
expected : (tag : Bool, payload : tag Type A Never);
received : (tag : Bool & tag == true, payload : A);
expected : Bool
received : (tag : Bool & tag == true)
f = (x : Either Int String) => (
x : (tag : Bool, payload : tag Type A B) = x;
(tag, payload : tag Type A B) = x;
()
);
a : (a : Int, b : Int) -> a == b
b : (a : _) -> _
((p : (a : Int, b : Int)) -> ((a : Int, b : Int) => a == b) p);
x => x
a : F (a = Int, b = String) -> ((a : Type, b : Type) => a) _B -> Int;
b : F (_A : _) -> ((a : Type, b : Type) => a) _A -> Int;
a : (a : Int, b : Int) => a;
b : (_x : _A) => _b;
a : ((a, b) : (a : Int, b : Int)) => a
b : (_x : _B) => _b;
x = (p : (a : Int, b : Int)) -> ((a : Int, b : Int) => a == b);
a : (a : Int, b : Int) => a;
b : (x : _A) => _b;
C_bool = (A : Type) -> A -> A -> A;
c_true : Bool = A => t => f => t;
c_false : Bool = A => t => f => f;
Ind_bool b = (P : Bool -> Type) -> P c_true -> P c_false -> P b;
Bool = (b : Bool & Ind_bool b);
true : Bool = X => t => f => t;
false : Bool = X => t => f => t;
ind_bool : (b : Bool) -> P -> P true -> P false -> P b =
b => P => p_t => p_f => (
(m, b1_eq_m1, p_m) =
b.2
(x => (m : Bool, x_eq_m1 : x == m.1, p_m : P m))
(true, refl, p_t)
(false, refl, p_t);
b_eq_m : b == m = b1_e1_m1;
(p_m : _[m := b | b_eq_m]);
);
(t => f => t) : A. A -> A -> A;
expected : (P : Bool -> Type) -> P true -> P false -> P b;
received : (A : Type) -> A -> A -> A;
pure : A. A -> IO A;
bind : A. B. (A -> B) -> IO A -> IO B;
handle : (A. Effect A -> A) -> K. (() -> Effect K) -> K
or = Read A;
Read | Write
read : E. () -> Read `or` E $-> String;
write : E. () -> Write `or` E $-> String;
And : (A : Type) -> (B : Type) -> Type;
Level : Type¹
f = (x : Nat `And` x == 1)
f : () -> (A => Read A | Write A) String;
⊥ = (A: *) -> A;
¬ φ === φ -> ⊥;
℘ S === (L : Level) -> S -> Type L;
U : Type 1 = (L : Level) -> (X : Type L) -> (℘℘X -> X) -> ℘℘X;
τ (t: ℘℘U) = (L : Level) => (X : Type L) => (f : ℘℘X -> X) => (p : ℘X) =>
t L (L2 => (x : U) => p L2 (f (x L X f)));
σ (s: U) : ℘℘U = s 1 U τ;
∆ = (y: U) => (p: ℘U) -> σ y p -> p (τ (σ y));
Ω : U = τ ((p: ℘U) => (x: U) -> σ x p -> p x);
℘ S === (L : Level) -> S -> Type L;
U : Type 1 = (L : Level) -> (X : Type L) -> (℘℘X -> X) -> ℘℘X;
τ : ((L : Level) -> ℘U -> Type L) -> U;
σ : U -> ((L : Level) -> ℘U -> Type L);
Ω : U = τ (L => (p: ℘U) => (x: U) -> σ x L p -> p L x);
Id = (A : Type) -> (x : A) -> A;
id = (A : Type) => (x : A) => x;
Bool = (A : Type) -> (t : A) -> (f : A) -> A;
true : Bool = A => t => f => t;
false : Bool = A => t => f => f;
ind_bool : b => (P : Bool -> Type) -> P true -> P false -> P b = _;
match_bool_with_eq :
{A} -> (b : Bool) ->
(t : (b == true) -> A) ->
(f : (b == false) -> A) -> A = _;
Compare = {A} -> (x : A) -> (y : X) -> Either (x == y) (x <> y);
Either A B = (tag : Bool, payload : tag Type A B);
f = (x : Either Int String) =>
x
| (tag = true, payload) => Int.to_string payload
| (tag = false, payload) => payload;
Term =
| x
| (x : Term) -> Term
| (x : Term) => Term
| Term Term
| (a : Term, b : Term)
| (a = Term, b = Term)
| (x, y) = Term; Term
norm
| <x> => <x>
| <(p : A) -> r> => norm_forall <(p : A) -> r>
| <(p : A) => r> => norm_lambda <(p : A) => r>
| <lambda arg> => norm_apply <lambda arg>;
norm_forall =
| <(x : A) -> B> =>
A = norm A;
B = norm B;
<(x : A) -> B>
| <(p : A) -> B> =>
norm <(x : A) -> ((p : A) => B) x>;
norm_lambda =
| <(x : T) => r> =>
T = norm T;
r = norm r;
<(x : T) => r>
| <(x : A, y : B) => r> =>
A = norm A;
B = norm B;
r = norm r;
<(x : A, y : B) => r>
| <(p1 : A, p2 : B) => r> =>
norm <
(z : (p1 : A, p2 : B)) =>
(x : A, y : B) = z;
(p1 : A) = x;
(p2 : B) = y;
r
>;
norm_apply1
| <lambda arg> =
// TODO: norm head?
lambda = norm lambda;
arg = norm arg;
norm_apply2 <lambda arg>;
norm_apply2
// apply
| <((x : A) => r) arg> =>
norm (r[x := arg])
// fst
| <((x : A, y : B) => x) (x = arg_x, y = _)> =>
<arg_x>
// snd
| <((x : A, y : B) => y) (x = _, y = arg_y)> =>
<arg_y>
// unpair
| <((x : A, y : B) => r) arg> =>
arg_x = <((x : A, y : B) => x) arg>;
arg_y = <((x : A, y : B) => y) arg>;
norm (r[x := arg_x][y := arg_y])
// normal
| <lambda arg> => <lambda arg>
norm_exists =
| <(p : A, _ : B)> =>
A = norm A;
B = norm <((p : A) => B) x>;
<(x : A, _ : B)>;
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1, d = d);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1, d = d);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1, d = d);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1, d = d);
f = (
(a : Int, b : Int) = a_b;
(c : Int, d : a == c) = c_d;
a + b + c
)[c_d := (c = 1, d = d)];
Either A B =
| (tag = "left", payload : A)
| (tag = "right", payload : B);
f = (x : Either Int String) =>
[%match x
| (tag = "left", payload) => Int.to_string payload
| (tag = "right", payload) => payload];
f = ((a : Int, b : Int), (c : Int, d : a == c)) => a + b + c;
f = (a_b_c_d : (a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c))) => (
(a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) = a_b_c_d;
(a : Int, b : Int) = a_b;
(c : Int, d : a == c) = c_d;
a + b + c
);
f = (a_b_c_d : (a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c))) =>
((a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) => (
(a : Int, b : Int) = a_b;
(c : Int, d : a == c) = c_d;
a + b + c
)) a_b_c_d;
f = (a_b_c_d : (a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c))) =>
((a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) => (
((a : Int, b : Int) => (
(c : Int, d : a == c) = c_d;
a + b + c
)) a_b
)) a_b_c_d;
f =
(a_b_c_d : (a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c))) =>
((a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) =>
((a : Int, b : Int) => ((c : Int, d : a == c) => a + b + c) c_d) a_b) a_b_c_d;
f = ((a : Int, b : Int) => (c : Int, d : a == c) => a + b + c) a_b (c = 1; d = d);
f = ((a : Int, b : Int) => a + b + 1) a_b
f =
((a : Int, b : Int) =>
(c_d : (c : Int, d : a == c)) =>
((c : Int, d : a == c) => a + b + c) c_d) a_b (c = 1; d = d);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1; d = d);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1; d = d);
f = (
(a : Int, b : Int) = a_b;
a + b + 1
);
f =
((a : Int, b : Int) => (c_d : (c : Int, d : a == c)) =>
((c : Int, d : a == c) => a + b + c) c_d); a_b :: (c = 1; d = d) :: []
f =
((a : Int, b : Int) =>
((c : Int, d : a == c) => a + b + c) (c = 1; d = d)); []
f = ((a : Int, b : Int) => a + b + 1) a_b;
E = (a : Int, (b, c) : (b : Int, c : Int));
E = (a : Int, b_c : (b : Int, c : Int));
E = ((a, b) : (a : Int, b : Int), a_eq_b : a == b);
E = (a_b : (a : Int, b : Int), a_eq_b : ((a : Int, b : Int) => a == b) a_b);
f = (a : Int, b : Int) => a == b;
f = (a_b : (a : Int, b : Int)) => ((a : Int, b : Int) => a == b) a_b;
f = (a : Int, b : Int) -> a == b;
f = (a_b : (a : Int, b : Int)) -> ((a : Int, b : Int) => a == b) a_b;
f = (a_b : (a : Int, b : Int)) -> ((a : Int, b : Int) => a == b) a_b;
f = (a_b : (a : Int, b : Int)) -> ((a : Int, b : Int) => a == b) a_b;
f = (((a : Int, b : Int), c : Int) => a + b + c) (a_b = a_b, c = 1);
f = (((a : Int, b : Int), c : Int) => a + b + c) (a_b = a_b, c = 1);
f = (((a : Int, b : Int), c : Int) => ((a : Int, b : Int) => a + b + c) a_b) (a_b = a_b, c = 1);
f = (((a : Int, b : Int) => a + b + 1) a_b);
f = ((a : Int, b : Int), (c : Int, d : a == c)) => a + b + c;
f = ((a : Int, b : Int), (c : Int, d : a == c)) => a + b + c;
f =
((a : Int, b : Int), c_d : (c : Int, d : a == c)) =>
((c : Int, d : a == c) => a + b + c) c_d;
f =
(a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) =>
((a : Int, b : Int) => ((c : Int, d : a == c) => a + b + c) c_d) a_b;
f =
(a_b_c_d : (a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c))) =>
((a_b : (a : Int, b : Int), c_d : (c : Int, d : a == c)) =>
((a : Int, b : Int) => ((c : Int, d : a == c) => a + b + c) c_d) a_b) a_b_c_d
f =
(a_b_c : (a_b : (a : Int, b : Int), c : Int)) =>
((a_b : (a : Int, b : Int), c : Int) =>
((a : Int, b : Int) => a + b + c) a_b) a_b_c;
f = (a_b : (a : Int, b : Int)) => f a_b;
f = (a : Int, b : Int) => f (a = a, b = b);
f = (a_b : (a : Int, b : Int)) =>
((a : Int, b : Int) => f (a = a, b = b)) a_b;
f = (a_b_c : ((a : Int, b : Int), c : Int)) => (((a : Int, b : Int), c : Int) => a + b + c) a_b_c;
f = (a_b_c : ((a : Int, b : Int), c : Int)) => (((a : Int, b : Int), c : Int) => a + b + c) a_b_c;
f = (((a : Int, b : Int), c : Int) => a + b + c) (a_b = a_b, c = 1);
f = ((a : Int, b : Int) => a + b + 1) a_b);
f = (a : Int, b : Int) => ();
f = (a_b : (a : Int, b : Int)) => ();
f = (a_b : (a : Int, b : Int)) => ();
id : (A : 0 : Type) -> (x : 1 : A) -> A;
id = (A : 0 : Type) => (x : 1 : A) => x;
double = (x : 2 : Int) => x + x;
with_x : ((x : 1 : Int) -> Int) -> Int;
// fails
x = with_x (x => double x);
(Bool, true, false, ind_bool) = (
Bool = A. A -> A -> A;
true : Bool = t => f => t;
false : Bool = t => f => f;
Bool = (b : Bool) & (P. P true -> P false -> P b);
true : Bool = t => f => t;
false : Bool = t => f => t;
ind_bool : (b : Bool) -> P -> P true -> P false -> P b =
b => P => p_t => p_f => (
(m, b_eq_m, p_m) =
b
(x => (m : Bool, x_eq_m1 : x == m, p_m : P m))
(true, refl, p_t)
(false, refl, p_t);
(p_m : _[m := b | b_eq_m]);
);
(Bool, true, false, ind_bool);
);
Either A B =
| (tag = true, payload : A)
| (tag = false, payload : B);
f = (x : Either Int String) => (
(tag : Bool, payload : tag Type Int String) = x;
payload
);
F = (x : Either Int String) ->
((tag : Bool, payload : tag Type Int String) -> payload) x
f = (x : Either Int String) =>
((tag : Bool, payload : tag Type Int String) => payload) x
f = (x : Either Int String) => (
(tag : Bool, payload : tag Type Int String) = x;
payload
);
f = (x : Int) => (
x
| (tag = true, payload) => Int.to_string payload
| (tag = false, payload) => payload
);
id = (L : Level) => (A : Type L) => (x : A) => x;
f = (b : Bool & b == true);
with_linear_int : (cb : (x : 1 : Int) -> Int) -> Int = _;
x = with_linear_int (x => x + x);
id = (A : 0 : Type) => (x : A) => x;
rewrite =
(A : Type) => (B : Type) =>
(x_eq_y : 0 : A == B) =>
(x : 1 : A) => (x : A[A := B | x_eq_y]);
Map Key Value : {
find : (key : Key) -> (map : @Map) -> Value;
find_and_remove : (key : Key) -> (map : @Map) -> (Value, @Map);
} = _;
// Church booleans
C_bool : Type 1 = (L : Level) -> (A : Type L) -> A -> A -> A;
c_true : Bool = L => A => t => f => t;
c_false : Bool = L => A => t => f => f;
// Induction principle
I_bool = b : Type 1 => (L : Level) -> (P : C_bool -> Type L) -> P c_true -> P c_false -> P b;
// Without IUP, Bool would be placed on Type Omega, making it useless
Bool : Type 1 = (b : Bool) & (ind : I_bool b);
true : Bool = L => X => t => f => t;
false : Bool = L => X => t => f => t;
ind_bool : (b : Bool) -> (L : Level) -> (P : Bool -> Type L) -> P true -> P false -> P b =
b => L => P => p_t => p_f => (
(m, b1_eq_m1, p_m) =
b.2
L
(x => (m : Bool, x_eq_m1 : x == m.1, p_m : P m))
(c_true, refl, p_t)
(c_false, refl, p_f);
// b.1 == m.1 implies in b == m
b_eq_m : b == m = b1_eq_m1;
// use b == m to change P m into P b
(p_m : _[m := b | b_eq_m]);
);
C_sigma = (A : Type) => (B : A -> Type) =>
(K : Type) -> ((x : A) -> (y : B x) -> K) -> K;
c_exist = A => B => x => y : C_sigma A B => K => f => f x y;
I_sigma = (A : Type) => (B : A -> Type) => s =>
(P : C_sigma A B -> Type) ->
((x : A) -> (b : B x) -> P (c_exist A B x y)) ->
P s;
Sigma = A => B => (s : C_sigma A B) & (ind : I_sigma s);
exist = A => B => x => y : Sigma A B => X => f => f x y;
ind_sigma = A => B => x => y => s => (P : Sigma A B -> Type) => (p_e : P (exist A B x y)) =
(m, s1_eq_m1) =
s.2
(x => (m : Sigma, x_eq_m1 : x == m.1, p_m : P m))
(x => y => (exist A B x y, refl, p_e));
C_sigma = (L : Level) => (A : Type L) => (B : A -> Type L) =>
(K_L : Level) -> (K : Type K_L) -> ((x : A) -> (y : B x) -> K) -> K;
c_exist = L => A => B => x => y : C_sigma A B => K_L => K => f => f x y;
Exists : Type 2 = ((K_L : Level) -> (K : Type K_L) -> ((x : Type 1) -> (y : x) -> K) -> K);
x = c_exist 1 Type (A => A) Nat 1;
I_sigma = (A : Type) => (B : A -> Type) => s =>
(P : C_sigma A B -> Type) ->
((x : A) -> (b : B x) -> P (c_exist A B x y)) ->
P s;
Sigma = A => B => (s : C_sigma A B) & (ind : I_sigma s);
exist = A => B => x => y : Sigma A B => X => f => f x y;
C_sigma = (A : Type) => (B : A -> Type) =>
(K : Type) -> ((x : A) -> (y : B x) -> K) -> K;
c_exist = A => B => x => y : C_sigma A B => K => f => f x y;
I_sigma = (A : Type) => (B : A -> Type) => s =>
(P : C_sigma A B -> Type) ->
((x : A) -> (b : B x) -> P (c_exist A B x y)) ->
P s;
Sigma = A => B => (s : C_sigma A B) & (ind : I_sigma s);
exist = A => B => x => y : Sigma A B => X => f => f x y;
C_bool : Type 1 = (A : Type L) -> A -> A -> A;
c_true : Bool = A => t => f => t;
c_false : Bool = A => t => f => f;
// Induction principle
I_bool = b => (P : C_bool -> Type) -> P c_true -> P c_false -> P b;
// Without IUP, Bool would be placed on Type Omega, making it useless
Bool : Type 1 = (b : Bool) & (ind : I_bool b);
true : Bool = L => X => t => f => t;
false : Bool = L => X => t => f => t;
t : (x : A) & B;
t.2 : B[x := t.1]
Equal : (A : Type) -> (x : A) -> (y : A) -> Type;
refl : (A : Type) -> (x : A) -> Equal A x x;
subst :
(A : Type) ->
(x : A) ->
(y : A) ->
(x_eq_y : x == y) ->
(P : A -> Type) ->
P x ->
P y;
symm = A => (x : A) => y => (x_eq_y : x == y) =>
subst A x y x_eq_y
(n => n == x)
(refl A x);
((X : _) => (x : _) => x) : (A : Type) -> (x : A) -> A;
(b : (A : Type) -> A -> A -> A) &
((P : ((A : Type) -> A -> A -> A) -> Type) -> (P ((A\1 : Type) => (t : A) => (f : A) => t)) -> (P ((A\2 : Type) => (t\1 : A) => (f\1 : A) => f)) -> P b)
id = (x : _A) => x;
expected :: (A : Type) -> (x : A) -> A;
received :: (X : Type) -> (y : X) -> X;
expected :: (A : \1) -> (x : \1) -> \2;
received :: (X : \1) -> (y : \1) -> \1;
with_context : {A} -> ({K} -> Context -> (A -> K) -> K) -> _;
with_offset : Side -> Offset.t -> (() -> T 'A) -> T 'A
norm 0 [] <((A : Type\1) => (x : A\1) => (y : A\2) => (x\2 : A\3)) Type\1>;
norm -1 [A := Type\1] <(x : A\1) => (y : A\2) => (x\2 : A\3)>;
norm -1 [A := Type\1] <(x : A\1) => (y : A\2) => (x\2 : A\3)>;
((x : A\1) => x\1)\-1[A := Type\1]
((x : A\1) => x\1)\-1[A := Type\1]
((x : A\1) => x\1)\-1[A := Type\1]
l : (x : A) -> B a : A
-------------------------
l a : ((x : A) => B) a
l : (x : A) -> B a : A
-------------------------
l a : B[x := a]
a : (A : Type) -> _C -> (A\2 -> A\3) -> _C\2
b : (X : Type) -> _D -> _B -> _B\1
a : (A : Type) -> _C -> (A\2 -> A\3) -> _C\2
b : (X : Type) -> _C -> _B -> _B\1
a : (A : Type) -> _C -> (A\2 -> A\3) -> _C\2
b : (X : Type) -> _C -> (A\2 -> A\3) -> (A\2 -> A\3)\1
a : (A : Type) -> _C -> (A\2 -> A\3) -> _C\2
b : (X : Type) -> _C -> (A\2 -> A\3) -> (A\2 -> A\3)\1
a : 2 : _C\2
b : 1 : (A\2 -> A\3)
_C := (A\2 -> A\3)\-1
a : 0 : [] : (A : Type) -> ((B : Type) -> (A\1 -> B\1)\2)\-1 = (A : Type) -> (B : Type) -> A\2 -> B\2
a : -1 : [Bound] : (B : Type) -> (A\1 -> B\1)\2 = (B : Type) -> A\2 -> B\2
a : 1 : [Bound, Bound] : A\1 -> B\1 = A\2 -> B\2
a : 1 : [Bound, Bound] : A\1 = A\2
a : 1 : [Bound, Bound] : B\1 = B\2
(e : A) === (((x : A) => x) e) === e
succ : Nat -> Nat = _;
(((x : Int) => succ x) 0);
succ (((x : Int) => x) 0);
(L : Level) -> (T : Type L, x : T)
(A : Type) -> A
(A : Type) -> (x : A) -> A
(A : Type\1) ->
norm [Bound, Bound] ((x : A\1) -> (A\2 : Type\3))
x = ((A : Type) => A : (A : Type) -> )
(\1 -> \1)+1~
(A -> A)\[a.te:0:1 .. a.te:1:2]
index
#+-offset
#[a.te:0:1 .. a.te:1:2]
(A : Type) => (A : Type) => (x : A\1) => x;
add = (a, b) => a + b;
(x : Bool) = 1;
((id : (A : \1 : (\1 : \1)) -> (x : \1 : (\1 : (\2 : \2)) -> (\2 : (\1 : (\1 : \1))#+2)) => (\1 : ((A : \1 : (\1 : \1)) -> (x : \1 : (\1 : (\2 : \2)) -> (\2 : (\1 : (\1 : \1))#+2))#+1)) ((A : \1) => (x : \1) => (\1 : \1#+1))
C_sigma A B = (K : Type) -> ((l : A) -> (r : B l) -> K) -> K;
c_pair A l B r : C_sigma A B = K => f => f l r;
Sigma = A => (x : A) => B => (y : B x) => (
);
f = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1, d = d);
C_bool = (A : Type) -> A -> A -> A;
c_true : C_bool = A => t => f => t;
c_false : C_bool = A => t => f => f;
Ind_bool = b => (P : C_bool -> Type) -> P c_true -> P c_false -> P b;
Bool = (b : C_bool) & Ind_bool b;
Bool = (b !: C_bool & ind : Ind_bool b)
ind_true : I_bool c_true = P => p_c_t => p_c_f => p_c_t;
ind_false : I_bool c_false = P => p_c_t => p_c_f => p_c_f;
Never = (A : Type) -> A;
rec%Fix = (self : Fix) -> Never;
Bool = rec%self. (
c : C_bool,
ind : Ind_bool c,
inj : 0 : (x : Bool) -> fst self == fst x -> self == x
);
true = rec%self. (c = c_true, ind = i_true, inj = y => fst_self_eq_fst_y => (
(_, _, x_inj) = x;
y_eq_self : fst y == fst self -> y == self) = x = y_inj self (symm fst_self_eq_fst_y);
symm y_eq_self;
));
fst a == fst b -> a == b
true : Bool = _;
false : Bool = _;
ind_bool = b => P => p_t => p_f => (
(x : Bool, c_b_eq_c_x : fst b == fst x, p_x : P x) =
(snd b) _ (true, refl, p_t) (false, refl, p_f);
)
Term =
| Var (String)
| Lambda (String, Term, Term)
| Apply (Term, Term)
| Type
| Forall (String, Term, Term)
| Mu (String, Term);
( == ) = A => (x : 0 : A) => (y : 0 : A) => (P : A -> Type) -> P x -> P y;
(refl : (A : Type) -> (x : 0 : A) -> x == x) =
A => x => P => p_x => p_x;
(symm : (A : Type) -> (x : 0 : A) -> (y : 0 : A) -> x == y -> y = x) =
A => x => y => x_eq_y => x_eq_y (z => z == x) (refl A x);
C_bool = (A : Type) -> A -> A -> A;
(c_true : C_bool) = A => t => f => t;
(c_false : C_bool) = A => t => f => f;
Ind_bool b = (P : C_bool -> Type) -> P c_true -> P c_false -> P b;
Y : (A : Type) -> (A -> A) -> A = f => (
fix = (x : @S. S -> A) => f (x x);
fix fix
);
Nat = @Nat. (A : Type) -> (zero : A) -> (succ : Nat -> A) -> A;
Pair A B = (K : Type) -> ((l : A) -> (r : B l) -> K) -> K;
pair A x B y : Pair A B = K => f x y;
fst A B (pair : Pair A B) = pair A (l => r => l);
snd A B (pair : Pair A B) = pair (B (fst A B pair)) (l => r => r);
rec%(Bool : Type) = Pair C_bool (comp => (
ind : Ind_bool b,
rel : (x : Bool) -> self.comp == x.c -> self == x
));
P_bool Rel = (comp : C_bool, rel : Rel);
X = rec @@ Rel =>
(x : P_bool Rel) ->
fst comp == fst x ->
Pair C_bool
(Rel : C_bool -> Type) =>
(K : Type) -> (
(comp : C_bool) ->
(ind : Ind_bool comp) ->
(rel : rec Rel @@
(x : Bool) ->
comp == (x C_bool (comp => _ => _ => comp)) -> self == x
) -> K)
-> K;
Rel = (comp : C_bool) =>
P_bool (Rel : C_bool -> Type) =
(K : Type) -> ((comp : C_bool) -> Ind_bool comp -> Rel comp -> K) -> K;
Make_rel = (Rel : C_bool -> Type) => (self : P_bool Rel) => (comp : C_bool) =>
(x : P_bool Rel) -> comp == (x C_bool (comp => _ => _ => comp)) -> self == x;
rec%(Bool : Type) = (
comp : C_bool,
ind : Ind_bool b,
rel : (x : Bool) -> self.comp == x.c -> self == x
);
rec%(self : Bool) => {
b : C_bool;
i : Ind_bool b;
p : (x : 1 : Bool) -> self.c == x.c -> self == x;
};
rec%(true : Bool) = {
b = c_true;
i = P => p_t => p_f => p_t;
p = x => true_c_eq_x_c => (
x_c_eq_true_c = symm A true.c x.c true_c_eq_x_c;
x_eq_true = x.p true x_c_eq_true_c;
symm A x true x_eq_true
);
};
rec%(Bool : Type) = rec%(self : Bool) => {
b : C_bool;
i : Ind_bool b;
p : 0 : (x : Bool) -> self.c == x.c -> self == x;
};
rec%(Fix : Type) = (self : Fix) -> (A : Type) -> A;
f = (1 : (
fix : Fix = fix => fix fix;
magic : (A : Type) -> A = fix fix;
));
// computing
C_bool B T F (S : B) = (A : Type) -> (S == T -> A) -> (S == F -> A) -> A;
(c_true : C_bool) = A => t => f => t;
(c_false : C_bool) = A => t => f => f;
// computing
C_bool = (A : Type) -> A -> A -> A;
(c_true : C_bool) = A => t => f => t;
(c_false : C_bool) = A => t => f => f;
// induction
I_bool b = (P : C_bool -> Type) -> P c_true -> P c_false -> P b;
i_true : I_bool c_true = P => p_t => p_f => p_t;
i_false : I_bool c_false = P => p_t => p_f => p_f;
// template
T_bool Rel = {
comp : C_bool;
ind : Ind_bool b;
rel : Rel;
};
Bool = {
comp : C_bool;
ind : Ind_bool b;
rel : Rel;
};
Bool = @Self((A : Type) => (self : T_bool A) => (x : T_bool A) -> self.comp == x.comp -> self == x);
true = %Self((self : Bool) => {
comp = c_true;
ind = i_true;
rel = x => self_comp_eq_x_comp => (
x_comp_eq_self_comp = symm self_comp_eq_x_comp;
x_eq_self = x.rel self x_comp_eq_self_comp;
symm x_eq_self
);
});
false = %Self((self : Bool) => {
comp = c_false;
ind = i_false;
rel = x => self_comp_eq_x_comp => (
x_comp_eq_self_comp = symm self_comp_eq_x_comp;
x_eq_self = x.rel self x_comp_eq_self_comp;
symm x_eq_self
);
});
ind_bool = b => (P : Bool -> Type) => (p_t : P true) => (p_f : P false) : P b => (
(m, b_comp_eq_m_comp, p_m) =
b.ind
(x => {m : Bool; x_eq_m_comp : x == m.comp; p_m : P m})
(true, refl, p_t)
(false, refl, p_f);
b_eq_m = b.rel b_comp_eq_m_comp;
m_eq_b = symm b_eq_m;
subst m_eq_b (x => P x) p_m
);
T[A := X]
T_bool ((x : Bool) -> self.comp == x.comp -> self == x)
rec%Bool (S : Bool) = (A : Type) -> (S == true -> A) -> (S == false -> A) -> A;
and%true : Bool true = A => t => f => t => t (refl true)
and%false : Bool false = A => t => f => ;
T_bool B T F (S : B) = (A : Type) -> (S == T -> A) -> (S == F -> A) -> A;
X = T_bool
Bool = @Self((A : Type) => (self : T_bool A) => (x : T_bool A) -> self.comp == x.comp -> self == x);
B : Type -> Type C : (A : Type) -> A -> Type
----------------------------------------------
@Self(A : Type, x : B A, C A x) : Type
Bool = {
comp : C_bool;
ind : Ind_bool b;
rel : (x : @Bool) => comp == x.comp -> @self == x;
};
rec%Fix = (self : N : Fix) -> (A : Never) -> A;
fix = (self : N : Fix) => self self;
```
## Compression
```rust
((A : Type\1) => (x : A\1) => x\1) Type\1
(A : Type\1) => ((x : A\2) => x\1)#-1;
((A : Type\1) => (x : A\1) => x\1)#+1
((x : A\0) => x\1)
((x : Type\1) => x\1)-1
(A : Type) => ((B : Type\1) => (x : B\1) => (x\1, A\3)) Type\2;
(A : Type) => (x : Type\1) => (x\1, A\2);
((A : \1) => (x : \1) => \1)#+1#-1
((A : \2) -> (x : ((A : \1) => (x : \1) => \1)#+2) -> ((A : \1) => (x : \1) => \1)#+3)#-1
((A : \1) -> ((x : \1) -> (\2 : (\1)#+2) : \2) : \1)#+1
((A : \1) -> ((x : \1) -> (\2) : \2) : \1)#+1
((A : \1 : (\0 : \0)#+1) -> ((x : \1 : (\1 : (\0 : \0)#+1)#+1) -> (\2 : (\1 : (\0 : \0)#+1)#+2) : \2) : \1)#+1
((A : Type\1) => (x : A\1) => x\1) Type\1
(x := Int; (1 : x))
(one : Int) = 1;
one_eq_1 : one == 1 = refl;
add = (a, b) => a + b;
(x = Int; (1 : x)) === (((x : Type) => (1 : x)) Int);
(x = print 1; (x, x));
(print 1, print 1);
(x : T = e1; e2) === (((x : T) => e1) e2)
(x : T := e1; e2) === (e2[x := e1]);
(x : T = e1; e2) === (((x : T) => e1) e2)
(x : T := e1; e2) === (e2[x := e1]);
x1 = (
(a : Int, b : Int) = a_b;
(c_d : (c : Int, d : a == c)) => (
(c : Int, d : a == c) = c_d;
a + b + c
)
) (c = 1; d = d);
x1 = (
(a, b) = a_b;
c_d => (
(c, d) = c_d;
a + b + c
)
) (c = 1; d = d);
// church encoding stucks
x1 =
a_b (a => b =>
c_d => c_d
(c => d =>
a + b + c)
) (k => k 1 d);
x1 = (
(a, b) = a_b;
c_d => (
(c, d) = c_d;
a + b + c
)
) (c = 1; d = d);
x1 = (
(a, b) = a_b;
c_d => (
(c, d) = c_d;
a + b + c
)
) (c = 1; d = d);
x1 = (
(a, b) = a_b\1;
c_d => (
(c, d) = c_d\1;
a\4 + b\3 + c\2
)
) (c = 1; d = 2);
x1 = (
(a, b) = a_b\1;
c_d => (
(c, d) = c_d\1;
a\4 + b\3 + c\2
)
) (c = 1; d = 2);
x1 = (
(a, b) = a_b\1;
c_d => (
(c, d) = c_d\1;
a\4 + b\3 + c\2
)
);
x =>
((a, b) => c_d => (
(c, d) = c_d\1;
a\4 + b\3 + c\2
)) a_b\1 (c = 1; d = 2) [id]
((a, b) => c_d => (
(c, d) = c_d\1;
a\4 + b\3 + c\2
)) a_b\1 (c = 1; d = 2) [id]
BetaPair : (((x, y) => c) (a, b)) == c[y := b; x := a; ...id]
StuckPair : (((x, y) => c) z)[s] == ((x, y) => c[id; id; s]) z
Unit = (A : Type) -> A -> A;
unit : Unit = A => x => x;
Pair (A : Type) (B : A -> Type) = (K : Type) -> ((x : A) -> B x -> K) -> K;
(pair A B x y) : Pair A B = K => k => k x y;
Bool = (A : Type) -> A -> A -> Pair A A;
true : Bool = A => x => y => pair A A x y;
false : Bool = A => x => y => pair A A y x;
Option A = (some : Bool, (T, _) = some Type A Unit; T);
some A (x : A) = (some = true, x);
dup_bool : Bool -> Pair (Pair Bool Bool) (Pair Bool Bool) =
b => b (Pair Bool Bool) (pair A B true true) (pair A B false false);
Nat = (X : Type) -> ((succ : Bool, zero Type X Unit) -> X) -> X;
zero : Nat = X => k => k (succ = false, unit);
succ : Nat -> Nat = n => X => k => n X k (succ = true, )
Nat = (A : Type) -> A -> ((K : Type) -> A -> A) -> Pair (A -> A) (A -> A);
zero : Nat = A => z => s => Pair (A -> A) (A -> A) z s;
succ : Nat -> Nat = n => A => z => s => s (n)
List A = X -> (((K : Type) -> (A -> X -> K) -> (Unit -> K) -> K) -> X) -> X;
(cons A el tl) : List A = X => k => k (K => cons => nil => cons )
(nil A) : List A = X => k => k (K => cons => nil => nil unit);
dup_list = (A : Type) => (l : List A) => ();
one =0> #0;
one =1> #1;
two => one => ((x => y => x\1 + two\3) one\0)
one => ((x => y => x#|1) one#1|0)
one => (y => one\1)
Int -> _A\0 -> _A\1;
Int -> {A} -> A -> A;
((id : (A : Type) -> (x : A) -> A) = A => x => x; id)
: (A : Type) -> (x : A) -> A)
( := ) : Ref A -> A -> Ref A;
add = (a, b) => a + b;
x = x := 1;
((fix $ 1 : _) => fix fix) ((fix $ 1 : _) => fix fix);
Nat N = (X : Type $ 0) -> (((R : Type $ 0) -> (X -> R) $ N -> R $ 1) $ 1 -> X) -> X;
two = (A : Type) => (z $ 1 : A) => (s $ 2 : A -> A) => s (s x)
double (x : Socket) =
(l : Int $ 1, r) = x;
(l : Int $ 1, r) = x;
x + x;
double (x : Pair (Int $ 1) Int) =
(l : Int $ 1, r) = x;
(l : Int $ 1, r) = x;
x + x;
zero = x => f => x;
succ = n => x => f => f (n x f);
one = x => f => f x;
two = x => f => f (f x);
zero = k => z => s => k z;
succ = n => k => z => s => s k z n;
one = k => z => s => s k z @@ k => z => s => k z;
two = k => z => s => z => s k z @@ k => z => s => z k s @@ k => z => s => k z;
rec%Nat = (K : Type) -> (A : Type) -> (k : A -> K) -> (z : A) ->
(s : (k : A -> K) -> (z : A) -> (p : Nat) -> K) -> K;
zero : Nat = K => A => k => z => s => k z;
succ (n : Nat) : Nat = K => A => k => z => s => s k z n;
Id = (A1 : Type) -> (A2 : Type) -> (A1_eq_A2 : A1 == A2) -> (x : A) -> A;
Id = (A $ 2 : Type) -> (x : A) -> A;
id = (A : Type) => (x : A)
// pure system F
Nat X = (K : Type) -> (A : Type) -> (k : A -> K) -> (z : A) ->
(s : (k : A -> K) -> (z : A) -> (p : X) -> K) -> K;
Nat_m = (X : Type) -> (Nat X -> X) -> X;
Nat_n = Nat Nat_m;
zero : Nat_n = K => A => k => z => s => k z;
in_ : Nat_n -> Nat_m = n => X => w => ;
succ : Nat_n -> Nat_n = n => K => A => k => z => s => s k z (in_ n);
// quantitative
rec%Nat Q = (K : Type) -> (A : Type) -> (k : A -> K) -> (z : A) ->
(s $ Q : (k : A -> K) -> (z : A) -> (p : Nat Q) -> K) -> K;
id = (A $ 0 : Type) => (x : A $ 1) => x;
y = ((x $ Omega) => x x) ((x $ Omega) => x x)
double = (x $ 2 : Int) => x + x;
Nat Q = (A : Type) -> (z : A) -> (s $ Q : A -> A) -> A;
zero : Nat 0 = A => z => s => z;
succ Q (n $ 1 : Nat Q) : Nat (Q + 1) = A => z => s => s (n A z s);
Z : (self : A -> B) -> A -[Z]> B;
Level : SLevel
Grade : SGrade
(A : Type (L, G))
Type (L : Level, G : Grade) : Type (L + 1, 0);
Erasable (L : Level) = Type (L, 0);
Linear (L : Level) = Type (L, 1);
Nat (G : Grade) : Type (1, G);
(x : Nat : Erasable) =>
----------------
(x : A) -> B
----------------
(x $ 0 : ) -> B
id : A. (x : A) -> A
Pair ()
Nat = (Q : Quantity, Nat Q);
zero : Nat 0 = K => A => k => z => s => k z;
succ Q (n $ 1 : Nat Q) : Nat (Q + 1) = K => A => k => z => s => s k z n;
// TODO: this Q is wrong internally
dup_nat = Q => K => fix%(self => k => (l, r) => (n : Nat Q) =>
n K (Nat Q, Nat Q) k (succ l, succ r) self);
Either A B =
| (tag = "left", x : A)
| (tag = "right", x : B);
// staged compilation
// boxing
f = (x : Nat & x >= 1) => x;
{x : Int & x >= 0}
l.1 == r.1 -> l == r?
// overloading
%( == ) :
(( == ) : {A} -> (x : A) -> (y : A) -> Type) &
(( == ) : {A : Eq} -> (x : A) -> (y : A) -> x == y);
( == ) : {A} -> (x : A) -> (y : A) -> Type;
%( == ) = {R} =>
(R, refl : R == R)
| (Type, eq : R == Type) => ( == )
( == ) = %( == );
Monad = {
pure : {A} -> (x : A) -> @M A;
bind : {A} -> (m : @M A, f : (x : A) -> @M B) -> @M B
};
map = (m, f) => bind(m, x => pure(f(x)));
map = {M : Monad} => (m, f) => M.bind(m, x => M.pure)
x = map {Option}
map = {M : _M_T}
C_bool = (A : Type) -> A -> A -> A;
c_true : C_bool = t => f => t;
c_false : C_bool = t => f => f;
Ind_bool : C_bool -> Type =
b => (P : Bool) -> P c_true -> P c_false -> P b;
ind_true : Ind_bool c_true = t => f => t;
ind_false : Ind_bool c_false = t => f => f;
C_bool = (A $ 0 : (tag = "c", Type)) -> (snd A) -> (snd A) -> (snd A);
c_true : C_bool = A => t => f => t;
c_false : C_bool = A => t => f => f;
I_bool : C_bool -> Type =
b => (P $ 0 : (tag = "i", Bool -> Type)) -> P c_true -> P c_false -> P b;
Bool = (b : C_bool) & I_bool b;
(T $ 0 : (tag = "i", Bool -> Type) | (tag = "c", Type)) ->
(P | (tag = "i", P) => P c_true | (tag = "c", A) -> A) ->
(P | (tag = "i", P) => P c_false | (tag = "c", A) -> t) ->
(P | (tag = "i", P) => P c_true | (tag = "c", A) -> A) <= (b : C_bool) & I_bool b;
(T $ 0 : (tag = "i", Bool -> Type)) -> (snd T) c_true -> (snd T) c_false -> (snd T) c_true <=
(P $ 0 : (tag = "i", Bool -> Type)) -> (snd P) c_true -> (snd P) c_false -> (snd P) c_true
(T $ 0 : (tag = "c", Type)) -> (snd T) -> (snd T) -> (snd T) <=
(A $ 0 : (tag = "c", Type)) -> (snd A) -> (snd A) -> (snd A);
Either A B = (K : Type) -> (A -> K) -> (B -> K) -> K;
true :
(T $ 0 : (tag = "i", Bool -> Type) | (tag = "c", Type)) =>
(t : P | (tag = "i", P) => P c_true | (tag = "c", A) -> A) =>
(f : P | (tag = "i", P) => P c_false | (tag = "c", A) -> f) =>
t;
Bool : Type = (b : C_bool) & Ind_bool b;
true : Bool = (b = c_true & ind_true);
false : Bool = (b = c_false & ind_false);
// resolution
b_true : (A $ 0 : Type) -> (B $ 0 : Type) -> A -> B -> A = A => B => t => f => t;
b_false (A $ 0 : Type) -> (B $ 0 : Type) -> A -> B -> B = A => B => t => f => f;
C_bool = (A $ 0 : Type) -> A -> A -> A;
I_bool : C_bool -> Type =
b => (P $ 0 : Bool -> Type) ->
P ((A : Type) -> b_true A A) ->
P ((A : Type) -> b_false A A) ->
P b;
Bool = (b : C_bool) & I_bool b;
true : Bool = b_true;
false : Bool = b_false;
[x | x => x -A | x => ]
[b_true
| (A : Type) -> b_true A A
| (P : Bool -> Type) -> b_true (P ((A : Type) -> b_true A A)) (P ((A : Type) -> b_false A A))
];
b_true : (A $ 0 : Type) -> (B $ 0 : Type) -> A -> B -> A = A => B => t => f => t;
b_false (A $ 0 : Type) -> (B $ 0 : Type) -> A -> B -> B = A => B => t => f => f;
C_bool = (A $ 0 : Type) -> A -> A -> A;
I_bool =
(A : Type) => (P : Bool -> Type) =>
P (b_true A A) ->
P (b_false A A) ->
P b;
Bool =
(A $ 0 : Type) ->
(P $ 0 : (A -> A -> A) -> Type) ->
(b : A -> A -> A) &
(P (b_true A A) -> P (b_false A A) -> P b);
(A : Type) -> b_true &(A; b => P (b A))
(b : (B $ 0 : Type) -> A -> B -> A) & ((B $ 0 : Type) -> P (b A A) -> B -> P (b A A))
S x =
| (y $ 0 : A) -> S
| (S x) -A
| x;
[x | i = ]
[b_true
| (A : Type) -> b_true A A (P : (A -> A -> A) -> Type) -> b_true ]
true : Bool = A => P => (
x
x = (A : Type) -> b_true &(A | _ => P (b_false A A));
);
((A $ 0 : Type) -> A -> A -> A) &
((A $ 0 : Type) -> A -> P (b_false A A) -> A)
((B $ 0 : Type) -> A -> B -> A) &
((B $ 0 : Type) -> (P (b_true A A)) -> B -> (P (b_true A A)))
(A $ 0 : Type) -> (B $ 0 : Type) -> A -> B -> A <: (b : C_bool) & I_bool b
_ <: (A $ 0 : Type) -> A -> A -> A
_ <: (P $ 0 : Bool -> Type) -> P (b_true :> Bool) -> P (b_false :> Bool) -> P (b_true :> Bool)
rec%Term =
| Var (x : String)
| Lambda (param : String) (body : Term)
| Apply (lambda : Term) (arg : Term);
rec%List A =
| []
| A :: List
rec%Tree A =
| Leaf A
| Node (Tree A, Tree A);
Node (Node (Leaf 1, Leaf 2), Node (Left 3, Leaf 4))
- Node (Leaf 1, Leaf 2)
- Leaf 1
- Leaf 2
- Node (Left 3, Leaf 4)
- Leaf 3
- Leaf 4
rec%fold = (f, acc, l) =>
l
| [] => []
| el :: tl => (
acc = f(acc, el);
fold(f, acc, tl)
);
rec%fold_right = (f, acc, l) =>
l
| [] => []
| el :: tl => (
acc = fold_right(f, acc, tl);
f(acc);
);
sum = (l) => fold((acc, el) => acc + el, 0, l);
rev = (l) => fold((acc, el) => el :: acc, [], l);
map = (f, l) => (
rev_f_l = fold((acc, el) => f(el) :: acc, [], l);
rev(rev_f_l)
);
rec%map = (f, l) =>
l
| [] => []
| el :: tl => f(el) :: map(f, tl);
rec%map = (f, l) =>
l
| [] => []
| el :: tl => map_cons(f, el, tl)
and%map_cons = (f, el, tl) => f(el) :: map(f, tl);
map_cons = map => (f, el, tl) => f(el) :: map(f, tl);
map_base = map => (f, l) => l | [] => [] | el :: tl => map_cons(map)(f, el, tl)
map_base = map => (f, l) => l | [] => [] | el :: tl => map(f, el, tl)
Y = f => (x => f(x(x)))(x => f(x(x)));
loop = (x => x(x))(x => x(x));
loop = (x => x(x))(x => x(x));
loop = (x => x(x))(x => x(x));
map = (x => map_base(x(x)))(x => map_base(x(x)));
map = map_base((x => map_base(x(x)))(x => map_base(x(x))));
map = map_base(map_base((x => map_base(x(x)))(x => map_base(x(x)))));
rec%map = (f, l) => map_base(map, f, l);
rec%Many A = (G : Grade) -> (A G, Many A);
rec%Fix = Fix $ Many -> Unit;
Int : G. Type (1, G);
{A} -> {M : Monad} -> M A -> M B;
f = G. (x : Int) => (
g : Unit -> Int = () => x;
(g(), g())
);
Type L G : Type (L + 1, 0)
f = (x : $Int) => (x, x : Int $ 0);
f = (A : Type) => A;
f = x => (
(x1, x) = x;
x1(x)
);
(x : (A : Type) -> A)
rec%Fix = (A : Type) -> (B : Type) -> (A -> B) -> A -> B;
%fix : (Type -> Type) -> Type;
fix = (A : Type) => (B : Type) => (f : %fix(K => ))
fix = (A : Type) => (f : %fix(K => K -> A)) : A => f(f)
%fix(Self => Self -> T) ===
%Mu : (W : Type -> Type) -> Type;
%mu : (W : Type -> Type) -> Mu W == W (Mu W);
%Mu(Self => Self -> T) == (%Mu(Self => Self -> T)) -> T
-------------------------------
Y : (A : Type) -> (A -> A) -> A
Equal A (x : A) (y : A) = (P : _) -> P x -> P y;
Bool = (H : )
T_bool = Type -> Type -> Type;
t_true : T_bool = t => f => t;
t_false : T_bool = t => f => f;
Bool (H : T_bool) = (A : Type) -> (H == t_true -> A) -> (H == t_false -> A) -> A
true : Bool t_true = A => t => f => t refl;
false : Bool t_false = A => t => f => f refl;
ind_bool
: (H : T_bool) -> (b : T_bool H) -> (P : T_bool -> Type) -> P t_true -> P t_false -> P H =
b => P => p_t => p_f =>
b p_t p_f
TRec F = (X : Type) ->
Rec F = (X : Type) -> (F X -> X) -> X;
M = Rec (X => (A : Type) -> A -> (X -> A) -> A);
N = Rec M;
T_nat = Type -> (Type -> Type) -> Type
t_zero : T_nat = z => s => z;
t_succ : T_nat -> T_nat = pred => z => s => s (pred z s);
t_add : T_nat -> T_nat -> T_nat = n => m => z => s => n (m z s) s;
t_add (t_succ n_t_pred) m_t == (z => s => s (n_t_pred (m_t z s) s))
t_succ (t_add n_t_pred m_t) == (z => s => s (n_t_pred (m_t z s) s))
rec%Nat (H : T_nat) =
(A : Type) ->
(H == t_zero -> A) ->
((t_pred : T_nat) -> H == t_succ t_pred -> Nat t_pred -> A) ->
A;
zero : Nat t_zero = A => z => s => z refl;
succ : (t_pred : T_nat) -> (pred : Nat t_pred) -> Nat (t_succ t_pred) =
t_pred => pred => A => z => s => s t_pred refl pred);
rec%add
: (n_t : T_nat) -> Nat n_t -> (m_t : T_nat) -> Nat m_t -> Nat (t_add n_t m_t)
= n_t => n => m_t => m => A => z => s =>
n (Nat (t_add n_t m_t))
(n_t_eq_t_zero => m)
(n_t_pred => n_t_eq_t_succ_n_t_pred => pred =>
x : Nat (t_add n_t_pred m_t) = add n_t_pred pred m_t m;
x : Nat (t_succ (t_add n_t_pred m_t)) = succ x;
t_add n (t_succ m));
Never = (A : Type) -> A;
Unit = (A : Type) -> A -> A;
unit : Unit = A => x => x;
z_neq_s_z (eq : t_zero == t_succ t_zero) =>
eq (n => n Unit (_ => Never)) unit;
rec%T_nat = Type -> (T_nat -> Type) -> Type;
t_zero : T_nat = z => s => z;
t_succ : T_nat -> T_nat = pred => z => s => s pred;
rec%t_add : T_nat -> T_nat -> T_nat = n => m => z => s =>
n m (n => t_add n (t_succ m));
rec%Nat (H : T_nat) =
(A : Type) ->
(H == t_zero -> A) ->
((t_pred : T_nat) -> H == t_succ t_pred -> Nat t_pred -> A) ->
A;
zero : Nat t_zero = A => z => s => z refl;
succ : (t_pred : T_nat) -> (pred : Nat t_pred) -> Nat (t_succ t_pred) =
t_pred => pred => A => z => s => s t_pred refl pred;
let f (type a) (ty : a ty) (x : a) =
match ty with Int -> string_of_int (x : int) | String -> (x : string)
type 'x nat_case' = { case : 'r. 'r -> ('x -> 'r) -> 'r }
type nat_iter = { iter : 'x. ('x nat_case' -> 'x) -> 'x }
type nat_case = nat_iter nat_case'
let zero_iter : nat_iter = { iter = (fun f -> f { case = (fun z _s -> z) }) }
let succ_iter : nat_iter -> nat_iter =
fun n ->
{
iter =
(fun (type x) (f : x nat_case' -> x) : x ->
f
{ case =
(fun (type r) (_z : r) (s : x -> r) : r -> s (n.iter f)) });
}
let in_ : nat_case -> nat_iter = fun n -> n.case zero_iter succ_iter
let zero_case : nat_case = { case = (fun z _s -> z) }
let succ_case : nat_case -> nat_case =
fun n -> { case = (fun _z s -> s (in_ n)) }
let out : nat_iter -> nat_case =
fun n -> n.iter (fun f : nat_case -> f.case zero_case succ_case)
let case (n : nat_case) z s = n.case z (fun pred -> s (out pred))
let iter (n : nat_case) z s = (in_ n).iter (fun n -> n.case z s)
let to_int (n : nat_case) = (in_ n).iter (fun n -> n.case 0 (fun n -> n + 1))
let () =
Format.printf "%d\n%!" (to_int (succ_case (succ_case (succ_case zero_case))))
A | B
A :> A | B
B :> A | B
A <: A | B
B <: A | B
A | B <: C
A <: C && B <: C
C <: A | B
C <: A || C <: B
(tag : true, Int) | (tag : false, String) <: (tag : Bool, tag Type Int String)
1 * 0 = 2 * 0
0 = 0
(1 * 0) / 0 = (2 * 0) / 0
1 = 2
(n * x) / x && x <> 0 == n
(1 * 0) / 0 = (2 * 0) / 0
(L : Level) -> (A : Type L, x : A)
Nat : {
@Nat : Type;
zero : Nat;
} = {
@Nat = Int;
zero = 0;
};
(==) :
((==) : {A} -> (x : A) -> (y : A) -> Type) &
{A : Eq} -> (x : A) -> (y : A) -> Option (x == y);
zero : Nat = Nat.zero;
f = (x : Int & x >= 0) => (x : Int);
S = {x : T | P x}
Nat = {x : Z | x >= 0};
Either A B =
| { tag = true; payload : A; }
| { tag = false; payload : B; };
M : {
T : Type;
x : T;
} = {
T = Int;
x = 1;
};
Id = (A : Type) -> A -> A;
id : Id = (A : Type) => (x : A) => x;
Bool = (A : Type) -> A -> A -> A;
true : Bool = (A : Type) => (x : A) => (y : A) => x;
false : Bool = (A : Type) => (x : A) => (y : A) => y;
Interval : UI;
Level : UL;
Grade : UG;
data%Bool = true | false;
ind%Eq (A : Type) (x : A) (y : A) : Type =
| refl : x == y;
Eq_refl : (A : Type) -> (x : A) -> Eq A x x;
Eq_ind : (A : Type) -> (x : A)
: (A : Type) -> (x : A) -> (P : (y : A) -> id x y -> Type) ->
P x (refl x) ->
((y : A) -> P y (nope x y)) ->
(y : A) -> (eq : id x y) -> P y eq
ind%Nat =
| O
| S (pred : Nat);
ind%Bool = | true | false;
Bool_ind :
(P : Bool -> Type) ->
(p_true : P true) ->
(p_false : P false) ->
(b : Bool) -> P b;
Bool_ind : (b : Bool, P : Bool -> Type, _ : P true, _ : P false) -> P b;
id<A>(x : A) = x;
Either(A, B) =
| (tag = true, x : A)
f = (x : Int | String) => (y : Int, x_eq_int : x == y) => (
)
f x == f y -> x == y
X B k == Y B k -> X A (x => x) = Y B (x => x)
X : (B : Type) -> (A -> B) -> Type;
k : A -> B
x => k (f x)
x => (f x)
// compute
fold : Bool -> (A : Type) -> A -> A -> A;
// induction
case :
(b : Bool) -> (P : Bool -> Type) ->
P true -> P false -> P b;
Eq A x y = (P : A -> Type) -> P x -> P y;
rec%Bool =
(A : Type) -> (P : Bool -> Type) -> P true -> P false -> P
(Eliminating a boolean B) shows that the boolean B is true or false.
Bool : Type = self%(b => (P : Bool -> Type) -> P true -> P false -> P b);
true : Bool = _;
false : Bool = _;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b = _;
Unit = (A : Type) -> A -> A;
unit : Unit = A => x => x;
Bool A T F = (H : A, ind : (P : A -> Type) -> P T -> P F -> P H);
Bool_0 = Bool Unit unit unit;
true_0 : Bool_0 = (H = _, ind = P => p_t => p_f => p_t);
false_0 : Bool_0 = (H = _, ind = P => p_t => p_f => p_f);
Bool_1 = Bool Bool_0 true_0 false_0;
true_1 : Bool_1 = (H = _, ind = P => p_t => p_f => p_t);
false_1 : Bool_1 = (H = _, ind = P => p_t => p_f => p_f);
Bool_2 = Bool Bool_1 true_1 false_1;
true_2 : Bool_2 = (H = _, ind = P => p_t => p_f => p_t);
false_2 : Bool_2 = (H = _, ind = P => p_t => p_f => p_f);
C_nat = (A : Type) -> A -> (A -> A) -> A;
c_zero : C_nat = A => z => s => z;
c_succ : C_nat -> C_nat => n => A => z => s => s z;
C_bool = (A : Type) -> A -> A -> A;
Bool (n : C_nat) =
n Type C_bool (A => (H : A, (P : A -> Type) -> P T -> P F -> P H));
case_2
: Bool_2 -> (A : Type) -> A -> A -> A
= (b : Bool_2) => (A : Type) => fst b (_ => A);
ind_2
: (b : Bool_2) -> (P : _ -> _) -> P true_1 -> P false_1 -> P (fst b)
= (b : Bool_2) => snd b;
Qual a melhor linguagem de programação?
- JavaScript
- PHP
- Python
JavaScript é a melhor linguagem de programação?
- Sim
- Não
Então Python é a melhor linguagem de programação?
Qual a mãe de todas as linguagens de programação?
Qual a melhor linguagem de programação? Por que JavaScript não é a melhor linguagem de programação?
Qual a melhor forma de conseguir o primeiro emprego?
Qual a forma você recomenda para conseguir o primeiro emprego?
Estou programando a 6 meses, qual a forma você recomenda para eu conseguir o primeiro emprego?
Como eu aprendo JavaScript?
- A: Ler livros sobre JavaScript
- B: Entrar em comunidades de JavaScript
- C: Ler a wikipedia sobre JavaScript
- D: Ver video no youtube sobre JavaScript
- E: Fazer um curso de 3k de JavaScript
Por que eu não aprendi JS com o livro X?
Por que os metodos acima não funcionaram?
-
A: Procuro no Google sobre JavaScript
Por que eu não consigo encontrar uma hipotese?
- Eu não tenho contexto o suficiente
Por que eu não consigo solucionar esse problema em X?
- A: Eu não sei X o suficiente
Por que eu não tenho uma hipotese?
data%Bool =
| true
| false;
pair A B (x : A) (y : B x) =
(K : Type) => k => k x y;
Sigma A B =
%self(Sigma, s).
(P : Sigma -> Type) ->
((x : A) -> (y : B x) -> P (%fix(Sigma, s). P => k => k x y)) ->
P s
Sigma A B =
%self(Sigma, s).
(P : Sigma -> Type) ->
((x : A) -> (y : B x) -> P (%fix(Sigma, s). P => (k : _ -> _ -> P s) => k x y)) ->
P s;
%fix(Bool, b) =>
Bool =
%self(Bool, b).
(P : Bool -> Type) ->
P (%fix(Bool, b). P => ())
sigT_rect
: forall (A : Type) (P : A -> Type) (P0 : {x : A & P x} -> Type),
(forall (x : A) (p : P x), P0 (existT P x p)) ->
forall s : {x : A & P x}, P0 s
Unit = %fix(Unit). %self(u).
(P : Unit -> Type) ->
P (%fix(u). (P : Unit -> Type) => (x : P u) => x) ->
P u;
%unroll(%fix(u). (P : Unit -> Type) => (x : P u) => x)
%self(u). (P : Unit -> Type) -> P (%fix(u). (P : Unit -> Type) => (x : P u) => x) -> P u
%self(u). (P : Unit -> Type) -> P (%unroll(%fix(u). (P : Unit -> Type) => (x : P u) => x)) -> P u
(x ) => x
@(x) ->
@(x) =>
Unit = %fix(Unit : Type). %self(u).
(P : Unit -> Type) -> P u -> P u;
ctx = [];
fix0 = %fix(Unit). %self(u). (P : Unit -> Type) ->
P (%fix(u). (P : Unit -> Type) => (x : P u) => x) -> P u;
ctx = [];
fix1 = %self(u). (P : fix0 -> Type) ->
P (%fix(u). (P : fix0 -> Type) => (x : P u) => x) -> P u;
ctx = [u : fix1];
fix2 = (P : fix0 -> Type) ->
P (%fix(u). (P : fix0 -> Type) => (x : P u) => x) -> P u;
ctx = [P : fix0 -> Type; u : fix1];
fix3 = P (%fix(u). (P : fix0 -> Type) => (x : P u) => x) -> P u;
ctx = [P : fix0 -> Type; u : fix1];
u0 : ? = %fix(u). (P : fix0 -> Type) => (x : P u) => x;
u1 : %self(u). ? = (P : fix0 -> Type) => (x : P u0) => x;
u2 : %self(u). (P : fix0 -> Type) -> ? = (x : P u0) => x;
u3 : %self(u). (P : fix0 -> Type) -> P u0 -> P u0 = _;
u0 : %self(u). (P : fix0 -> Type) -> P u0 -> P u0 = _;
expected : fix0;
received : %self(u). (P : fix0 -> Type) -> P u0 -> P u0;
expected : %fix(Unit). %self(u). (P : Unit -> Type) ->
P (%fix(u). (P : Unit -> Type) => (x : P u) => x) -> P u;
received : %self(u). (P : fix0 -> Type) -> P u0 -> P u0;
expected : %self(u). (P : fix0 -> Type) -> P u0 -> P u;
received : %self(u). (P : fix0 -> Type) -> P u0 -> P u0;
Unit = %fix(Unit). %self(u).
(P :
(
%self(u). (P : -> Type) ->
P (%fix(u). (P : Unit -> Type) => (x : P u) => x) -> P u
) ->
Type
) ->
P (%fix(u). (P : Unit -> Type) => (x : P u) => x) ->
P u;
%self(u). P
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ |- M[x := %fix(x). M] : T
-------------------------------
%fix(x). M : T
%fix(u). (x : P u) => x
u : _A
(x : P u) -> _A
_A := %self(u). (x : P u) -> _A
%fix(u). (x : P u) => u : %self(u). (x : P u)
%fix(u : %fix(T). %self(u). (x : P u) -> T).
(x : P u) => u
%self(u). (x : P u) -> %fix(T). %self(u). (x : P u) -> T
%self(u). (x : P u) -> %fix(T). %self(u). (x : P u) -> T
%fix(T). %self(u). (x : P u) -> T
%self(u). %fix(T). (x : P u) -> T
unit
: %fix(Unit : Type). %self(u). (P : Unit -> Type) -> P u -> P u
= %fix(u). (P : Unit -> Type) => (x : P u) => x
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P unit -> P u;
ctx = [];
s0 = %fix(Unit : Type). %self(u). (P : Unit -> Type) -> P unit -> P u;
s1 = %self(u). (P : s0 -> Type) ->
P unit -> P u;
ctx = [u : s0]
s2 = (P : s0 -> Type) -> P unit -> P u;
ctx = [u : s0; P : s0 -> Type]
s3 = P unit -> P u;
expected : s0
received : %fix(Unit : Type). %self(u). (P : Unit -> Type) -> P u -> P u
expected : %fix(UnitA : Type). %self(u). (P : UnitA -> Type) -> P unit -> P u
received : %fix(UnitB : Type). %self(u). (P : UnitB -> Type) -> P u -> P u
s4 = P (%fix(u : s0). (P : s0 -> Type) => (x : P u) => x) -> P u;
expected : %fix(A). () -> A
received : %fix(B). () -> B
expected : %fix(C). () -> () -> A
received : %fix(C). () -> B
expected : () -> %fix(A). () -> A
received : () -> %fix(B). () -> B
Γ, x : Id |- T : Type
---------------------
%self(0, x. T) : Type
Γ, x : %self(i, x. T) |- T : Type
---------------------------------
%self(i + 1, x. T) : Type
Γ |- M[x := id] : T
---------------------
%fix(0, x : T. M) : T
Γ |- M[x := %fix(0, x : T. M)] : T
----------------------------------
%fix(i + 1, x : T. M) : T
%fix(i, Unit.
%self(i, u. (P : Unit -> Type) ->
P ((P : Unit -> Type) => (x : P u) => x) -> P u))
Unit = %fix(Unit). %self(u).
(P : Unit -> Type) -> P ((P : Unit -> Type) => (x : P u) => x) -> P u;
unit : Unit = %fix(u). (P : Unit -> Type) => (x : P u) => x;
%fix(Unit). %self(u).
(P : Unit -> Type) -> P ((P : Unit -> Type) => (x : P u) => x) -> P u
%fix(T). %self(u).
Γ, x : A |- B : Type A === %self(x : A). B
-------------------------------------------
%self(x : A). B : Type
Γ |- M[x := %fix(x : A). M] : B
--------------------------------
%fix(x : A). M : %self(u : A). B
%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x
%fix(Unit : Type). %self(u : Unit).
(P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) ->
P u;
%fix(Unit : Type). %self(u : Unit).
(P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) ->
P u;
%fix(u) : %fix(Unit : Type). (P : Unit -> Type) -> P u -> P u.
(P : Unit -> Type) => (x : P u) => x
%self(u : Unit). (P : Unit -> Type) -> P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
%self(u : Unit). (P : Unit -> Type) -> P u -> P u;
%fix(T : Type). %self(u : T). (P : T -> Type) -> P u -> P u
%fix(Unit : Type). %self(u : Unit).
(P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) ->
P u;
%fix(False) : Type. %self(f). (P : !False -> Type) -> P f
%fix(False) : Type. %self(f : !False). (P : !False -> Type) -> P f
%fix(False) : Type.
%self(f : (%self(f : False). (P : False -> Type) -> P f)). (P : !False -> Type) -> P f
(%self(f : False). (P : False -> Type) -> P f) ==
%self(f : False). (P : False -> Type) -> P f
!False <: False
f : (P : !False -> Type) -> P f
%fix(False) : Type. %self(f).
(P : (%self(f). (P : False -> Type) -> P f) -> Type) -> P f
%self(f). (P : !False -> Type) -> P f
%fix(Unit) : Type. %self(u).
(P : (%self(u). (P : Unit -> Type) -> P u -> P u) -> Type) ->
P (
%fix(u) : (P : Unit -> Type) -> P u -> P u.
(P : Unit -> Type) => (x : P u) => x
) -> P u
%fix(u : )
() = check (1 + 1) 2;
%fix(Unit : Type). %self(u : Unit).
(P : Unit -> Type) ->
P (
%fix(u) : (P : Unit -> Type) -> P u -> P u.
(P : Unit -> Type) => (x : P u) => x
) -> P u
Either A B =
| (left = true, content : A)
| (left = false, content : B);
Either A B = (left : Bool, content : Bool Type A B);
%fix(Unit : Type). %self(u : Unit).
(P : !Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
%fix(Unit : Type). %self(u : Unit).
(P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
Γ, x : A |- B : Type A === %self(x : A). B
-------------------------------------------
%self(x : A). B : Type
Γ |- M[x := %fix(x : A). M] : B A === %self(x : A). B
------------------------------------------------------
%fix(x : A). M : A
Γ |- M[x := [%fix(x : A). M[!x := x]]] : B A === %self(x : A). B
------------------------------------------------------
%fix(x : A). M : A
Γ |- M : %self(u : A). B
-------------------------------
%unroll(M) : B[u := %unroll(M)]
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
Unit = %fix(Unit : Type).
%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u;
!Unit === %self(u : !Unit). (P : !Unit -> Type) -> P u -> P u
![%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u] === %self(u : !Unit). (P : !Unit -> Type) -> P u -> P u
%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u === %self(u : !Unit). (P : !Unit -> Type) -> P u -> P u
Unit = %fix(Unit : Type).
%self(u : %self(u : !Unit). (P : !Unit -> Type) -> P u -> P u).
(P : (%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u) -> Type) ->
P u -> P u;
Unit = %fix(Unit : Type).
%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u;
Unit = %fix(Unit : Type).
%self(u : !Unit). (P : !Unit -> Type) -> P u -> P u;
Unit = %fix(Unit : Type).
%self(u : !). (P : !Unit -> Type) ->
P u -> P u;
unit
: %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P u -> P u
= %fix(u). (P : Unit -> Type) => (x : P u) => x;
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
%self(u : (%fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P unit -> P u)). (P : (%fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P unit -> P u) -> Type) -> P unit -> P u
%fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P u -> P u
unit = %fix(u : Unit). (P : Unit -> Type) => (x : P u) => x;
ind_unit = (P : Unit -> Type) => (p : (u : Unit) =>
u
(P : Unit -> Type) -> P unit ->
%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x
%self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
===
%self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
%self(u : Unit).
(P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
%self(u : Unit). (P : Unit -> Type) -> P u -> P u
unit
: %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P u -> P u
= %fix(u). (P : Unit -> Type) => (x : P u) => x;
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
%fix(true : Bool).
(P : Bool -> Type) => (then : P true) =>
(else : P (%fix(false : Bool).
(P : Bool -> Type) =>
(then : P (%fix(true). (P : Bool -> Type) => (then : P true) => (else : P false) => then)) =>
(else : P false) => else
)
Bool = %fix(Bool : Type). (
%self(b : Bool). (P : Bool -> Type) ->
P (%fix(true : Bool).
(P : Bool -> Type) => (then : P true) =>
(else : P (%fix(false : Bool). (P : Bool -> Type) => (then : P true) => (else : P false) => else)) =>
then) ->
P (%fix(false).
(P : Bool -> Type) =>
(then : P (%fix(true). (P : Bool -> Type) => (then : P true) => (else : P false) => then)) =>
(else : P false) =>
else)) ->
P b
)
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
False = %fix(False : Type). %self(f : False). (P : False -> Type) -> P f;
False === %self(f : False). (P : False -> Type) -> P f
Sigma === %fix(Sigma) => A => B =>
%self(s : Sigma A B). (P : Sigma A B -> Type) ->
((x : A) -> (y : B x) ->
P (%fix(s : Sigma A B). (P : Sigma A B -> Type) =>
(k : (x : A) -> (y : B x) -> P s) => k x y) ->
P s;
%self(s : Sigma A B). (P : Sigma A B -> Type) ->
((x : A) -> (y : B x) ->
P (%fix(s : Sigma A B). (P : Sigma A B -> Type) =>
(k : (x : A) -> (y : B x) -> P s) => k x y) ->
P s === %self(s : Sigma A B). (P : Sigma A B -> Type) ->
((x : A) -> (y : B x) ->
P (%fix(s : Sigma A B). (P : Sigma A B -> Type) =>
(k : (x : A) -> (y : B x) -> P s) => k x y) ->
P s
False = %fix(False : Type). %self(f). (P : False -> Type) -> P f;
False === %self(f). (P : False -> Type) -> P f
expected : Unit
received : %self(u : Unit). (P : Unit -> Type) -> P u -> P u
alias : u === %fix(u : Unit). (P : Unit -> Type) => (x : P u) => x
expected : %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
received : %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u
%fix(Y). Y -> ();
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
%fix(False : Type). %self(f : False). (P : False -> Type) -> P f;
False === %self(f : False). (P : False -> Type) -> P f
%self(f : False). (P : False -> Type) -> P f
False ===
%fix(False : Type). %self(f : False 1). (P : False 0 -> Type) -> P f;
Γ, x : A |- B : Type A === %self(x : A). B
-------------------------------------------
%self(x : A). B : Type
Γ, x : X, r : %self(r). Eq X M x |- M : X
------------------------------------------
%fix(x : X, r). M : X
%fix(Unit : Type, eq). %self(u). (P : Unit -> Type) ->
P (
%fix(u : Unit, r).
eq (T => T)
(P : Unit -> Type) => (x : P u) => x))
P (eq (T => T) u);
Eq A (x y : A) = (P : A -> Type) -> P x -> P y;
%fix(False : Type, eq).
%self(f). (P : False -> Type) -> P (eq (T => T) f);
Unit : Type
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
False : Type
False = %self(f). (P : False -> Type) -> P f;
Unit = %fix(False).
%self(u). (P : Unit unit -> Type) -> P unit -> P u;
The natural internalization of dependent elimination requires a term that depends on itself on the type level.
A term that depends on itself, is a term introduced by a fixpoint.
Such a fixpoint requires a type to represent the self dependency, we call that a self type.
// formation
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
// introduction
Γ |- M[x := M] : T
---------------------------
%fix(x). M : %self(x). T
A self type variable can only appear in a type constructor position, as such the expected type of such constructor must be the self type itself.
Due to that, the self type usage requires a type fixpoint. But such a type needs to be checkable against the self variable itself.
// somehow (f : False), to allow (P f)
%fix(False). %self(f). (P : False -> Type) -> P f
Somehow control the internal expansion
False : Type
False = %self(f : False). (P : False -> Type) -> P f
Unit = %fix(Unit : Type). %self(u : Unit). (P : Unit -> Type) ->
P (%fix(u : Unit). (P : Unit -> Type) => (x : P u) => x) -> P u;
unit : Unit = %fix(u : Unit). (P : Unit -> Type) => (x : P u) => x;
ind : (P : Unit -> Type) -> P unit -> (u : Unit) -> P u =
(P : Unit -> Type) => (x : P unit) => (u : Unit) => u P x;
f = (u : Unit) : Eq Unit u unit =>
u (u => Eq Unit u unit) eq_refl;
False = %fix(False : %self(False). (%self(f). False f) -> Type).
(f : %self(f). False f) => (P : False f -> Type) -> P f;
False = %self(f). False f;
Unit =
%fix(Unit : %self(Unit).
(u : %self(u). (unit : %self(unit). Unit u unit) -> Unit u unit) ->
(unit : %self(unit). Unit u unit) -> Type
). u => unit => (P : Unit u unit -> Type) -> P unit -> P (u unit);
unit = %fix(u). (unit : %self(unit). Unit u unit) ->
Unit =
%fix(Unit : %self(Unit).
(unit : %self(unit). (u : %self(u). Unit unit u) -> Unit unit u) ->
(u : %self(u). Unit unit u) -> Type
). unit => u => (P : Unit unit u -> Type) -> P (unit u) -> P u;
unit : %self(unit). Unit (_ => unit) unit =
(P : Unit (_ => unit) unit -> Type) => (x : P unit) => x;
Unit = %self(u).
Unit u (%fix(unit : ) : (P : Unit u unit -> Type) => (x : P unit) => x);
Unit =
%fix(Unit : %self(Unit).
(unit : %self(unit). (u : %self(u). Unit unit u) -> Unit unit u) ->
(u : %self(u). Unit unit u) -> Type
). unit => u => (P : Unit unit u -> Type) -> P (unit u) -> P u;
x = (f : False) =>
Unit = %fix(Unit : %self(Unit). (%self(unit). Unit unit) -> Type).
(unit : %self(unit). Unit unit) =>
(u : Unit unit) => (P : Unit unit -> Type) -> P unit -> P u;
unit = %fix(unit : %self(unit). Unit unit).
(u : Unit unit) => (P : Unit unit -> Type) => (x : P unit) => x;
%fix(False).
(eq : Eq Type (False eq) (%self(f : False eq, eq). (P : False eq -> Type) -> P f)) =>
%self(f : False eq, eq). (P : False eq -> Type) -> P f
// introduction
Γ, f : {f | x : A} -> B, x : A |- B : Type
------------------------------------------
{f | (x : A) -> B} : Type
{u | (P : _) -> P {u | P => x => x} -> P u}
Unit =
%fix(Unit : %self(Unit). (%self(u). Unit u) -> Type).
u => (P : Unit unit u -> Type) -> P u -> P u;
unit = %fix(u : Unit u). (P : Unit u -> Type) => (x : P u) => x;
fix%Unit (u : %self(u). Unit u) : Type = (P : Unit u -> Type) -> P u -> P u;
fix%unit : Unit unit = (P : Unit u -> Type) => (x : P unit) => x
Unit : (u : %self(u). Unit u) -> Type;
unit : %self(u). Unit u;
Unit = u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
unit = %fix(unit) : Unit unit. (P : (%self(u). Unit u)) => (x : P unit) => x;
fix%Unit (u : %self(u). Unit u) : Type = (P : Unit u -> Type) -> P u -> P u;
%self(unit). (u : %self(u). Unit unit u) ->
(P : Unit unit u -> Type) -> P (unit u) -> P (u => (P : Unit unit u -> Type) => (x : P (unit u)) => x))
unit = %fix(u). (unit : %self(unit). Unit u unit) ->
Unit = %fix(Unit : %self(Unit). (%self(u). Unit u) -> Type).
(u : %self(u). Unit u) => (P : (%self(u). Unit u) -> Type) -> P u;
False = %fix(False : %self(False). (%self(f). False f) -> Type).
(f : %self(f). False f) => (P : (%self(f). False f) -> Type) -> P f;
False = %self(f). False f;
Unit = %fix(Unit) : (unit : %self(u). Unit u u) -> (%self(u). Unit unit u) -> Type.
unit => u => (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
unit : %self(u). Unit u u = %fix(u) : Unit u u.
(P : (%self(u). Unit u u) -> Type) => (x : P u) => x;
Unit = %self(u). Unit unit u;
unit : Unit = unit;
Bool = %fix(Bool) :
(true : %self(true).
(false : %self(false). Bool (true false) false false) -> Bool (true false) false (true false)) ->
(false : %self(false). Bool (true false) false false) ->
(%self(b). Bool (true false) false b) -> Type.
true => false => b =>
(P : (%self(b). Bool (true false) false b) -> Type) -> P (true false) -> P false -> P b;
true : %self(true). (false : %self(false). Bool (true false) false false) -> Bool (true false) false (true false)
= %fix(true). false => (then : P (true false)) => (else : P false) => then;
false : %self(false). Bool (true false) false false
= %fix(false). (then : P (true false)) => (else : P false) => else;
Bool = %self(b). Bool (true false) false b;
true : Bool = true false;
false : Bool = false;
%self(False). (%self(f). False f) -> Type;
False : %self(f). False f -> Type
Unit : %self(Unit). (u : %self(u). Unit u) -> Type;
unit : %self(u). Unit u;
Unit = u => (P : %self(u). Unit u) -> P unit -> P u;
unit = P => x => x;
// tie the knot
Unit = %self(u). Unit u;
fix%False (f : %self(f). False f) : Type
= (P : (%self(f). False f) -> Type) -> P f;
False = %self(f). False f;
unit : %self(unit). Unit unit (%unroll unit)
%unroll unit : Unit unit (%unroll unit)
unroll Unit = (unit : %self(u). Unit u u) : %self(u). Unit unit u =>
%fix(u) : Unit unit u. unit : Unit unit unit;
fix%Unit (unit : %self(unit). Unit unit unit) (u : %self(u). Unit unit u) : Type
= (P : (%self(unit). Unit unit u) -> Type)-> P unit -> P u;
fix%unit : Unit unit (%unroll unit) =
(P : (%self(u). Unit unit u) -> Type) => (x : P (%unroll unit)) => x;
Unit = %self(u). Unit unit u;
%self(unit). Unit unit (%unroll unit)
%self(unit). Unit unit (%unroll unit)
%self(unit). (P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll unit)
fix%Unit (unit : %self(unit). Unit unit unit)
(u : %self(u). Unit unit u) : Type
= (P : (Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll u);
%self(u). Unit unit unit
%self(unit). Unit unit unit
fix%unit : %self(unit). Unit unit (%unroll unit) = %fix(u) : Unit unit u.
(P : (Unit unit u) -> Type) => (x : P (%unroll unit)) => x;
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll unit)
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x : %self(x). T |- M : T
----------------------------
%fix(x) : T. M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
False : _A
f : %self(f). _B
_A := _C -> Type;
_C := (%self(f). _B);
_B := False f;
f : %self(f). False f
False : (f : %self(f). False f) -> Type
False : lazy ((f : %self(f). False f) -> Type)
False : (f : lazy (%self(f). False f)) -> lazy Type
f : lazy (%self(f). False f)
// False f
False : (f : lazy (%self(f). False f)) -> lazy Type
%fix(False) : (f : %self(f). False f) -> Type. Type;
%fix(Unit): (unit : %self(unit). Unit unit (%unroll unit)) (u : %self(u). Unit unit (%unroll u))
= Type;
Unit : _A;
_A := (unit : _B) -> (u : _C) -> Type
unit : _B
_B := %self(unit). _D
(%unroll unit : _C)
(unit : _A) -> (u : _B) -> Type
_A === %self(unit). Unit unit (%unroll unit)
(%unroll unit : _B)
_B === %self(u). Unit unit (%unroll u)
(%unroll u : _B)
_A === %self(unit). Unit unit (%unroll unit)
fix%Unit (unit : %self(a). Unit a a) (u : %self(u). Unit unit u) : Type
= (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
fix%unit : Unit unit (%unroll unit) = P => x => x;
// external
Unit = %self(u). Unit unit (%unroll u);
unit : Unit = %unroll unit;
Because self requires assuming self, there are a couple ways of typing it.
Use an unification engine and after typing the content unify it against itself.
Accumulate all the clashes involved on the pending variable and check them afterwards.
Type the type without checking any of the types that depends on itself. Then type the type against the assumption and it should match.
%self(False). (f : %self(f). %unroll False f) -> Type
assume False (%self(False). _A);
check ((f : %self(f). %unroll False f) -> Type) _A
check (%self(f). %unroll False f) Type;
assume f (%self(f). _B);
check (%unroll False f) Type;
// TODO: accumulate substitution inside of unroll, like in Coq
check (%unroll False) (_C -> _D);
unify _A (_C -> _D);
check f _C;
unify _C (%self(f). _B);
unify _D Type
unify _B (%unroll False f);
check Type Type;
unify ((f : %self(f). %unroll False f) -> Type) ((f : %self(f). %unroll False f) -> Type)
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
False = %fix(False) : (f : %self(f). False f) -> Type.
f => (P : (%self(f). False f) -> Type) -> P f;
False = %self(f). False f;
Prop : Type
((A : Prop) -> (x : A) -> A) : Prop
fix%Unit
(unit : %self(unit). (u : %self(u). Unit unit u) -> Unit unit u)
(u : %self(u). Unit unit u) : Type
= (P : (%self(u). Unit unit u) -> Type) -> P (unit u) -> P u;
%self(False). (f : %self(f). False f) -> Type
%self(False, f). (P : False -> Type) -> P f;
%self(Unit). (unit : %self(a). Unit a a) -> (%self(u). Unit unit u) -> Type
%self(Unit). (unit : %self(unit). (u : %self(u). Unit unit u) -> Unit unit u)
(u : %self(u). Unit unit u) -> Type
%fix(Unit) : (A : Type) -> (unit : A -> A) -> (u : A) -> Type.
A => unit => u => (unit : %self(A, unit). Unit A u u) -> (%self(u). Unit unit u) -> Type.
%fix(Unit) : (A : Type) -> Type.
A => (wrap : A -> Unit A) -> (unit : Unit A) ->
%self(A, u). (P : Unit A -> Type) -> P unit -> P (wrap u);
%self(A, u). (P : (%self(A, f). Unit A f) -> Type) -> P unit -> P (wrap u)
// False
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
fix%Sigma A B
(pair : %self(pair).
(A : Type) -> (B : A -> Type) ->
(x : A) -> (y : B x) -> Sigma A B pair (pair A B x y))
(s : %self(s). Sigma A B pair s)
= pair => s =>
(P : (%self(s). Sigma A B pair s) -> Type) ->
((x : A) -> (y : B x) -> P (pair A B x y)) ->
P s;
Unit = %self(Unit, u).
(P : Unit -> Type) -> P (%fix(Unit, u). P => x => x) -> P u;
fix%unit : Unit unit = P => x => x;
Unit = Unit unit;
refl =>(%self(f : False). (P : False -> Type) -> P f) refl;
%fix(False).
A => x => (f : %self(A, f). False A f) -> Type
Γ, A : Type, x : B |- T : Type
------------------------------
%self(A, x : B). T : B[A := %self(A, x : B). T]
False = %self(A, f). False A f;
A term that does induction of itself, is a term that must mention itself on the type level. As terms are proofs those must be described by some proposition aka a type. So we need a proposition that can manipulate it's own proof.
This is similar to how impredicative polymorphism allows for a proposition to mention the universe where it itself inhabits.
How can a type mentions it's own term?
Major issue here is that all terms must have a valid type in context. And the term has the same type as the proposition that is still not typed.
-----------
Self : Type
Γ |- M : Self
----------------
%typeof M : Type
Γ |- M : Self
----------------------
%unpack M : %typeof M
Γ, x : Self |- T : Type
-----------------------
%self(x). T : Type
Γ |- M : %self(A, x). T
-----------------------
%unroll M : T[A := %self(A, x). T | x := M]
False : %self(False). (f : %self(f). False f) -> Type;
False = f => (P : (%self(f). False f) -> Type) -> P f;
// close
False = %self(f). False f;
False : %self(False). (f : %self(f). False f) -> Type;
// False must be callable inside of False
// False must be callable with (%self(f). False f) inside of False
False : %self(False). (f : Self) -> Type;
False = (A : Type) => (f : A) => (P : A -> Type) -> P f;
False = %self(A, f). (P : A -> Type) -> P f;
Unit = X => (unit : X) =>
%self(A, u). (P : (A : Type) -> (u : A) -> Type) -> P X unit -> P A u;
unit
: %self(X, unit). (P : (A : Type) -> (u : A) -> Type) -> P X unit -> P X unit
= %fix(X, unit). (P : (A : Type) -> A -> Type) => (x : P X unit) => x;
%unroll unit : %self(A, u). (P : (A : Type) -> (u : A) -> Type) ->
P (%self(X, unit). (P : (A : Type) -> (u : A) -> Type) -> P X unit -> P X unit) unit ->
P A u
Unit = Unit (%self(X, unit). Unit X unit) unit;
unit : %self(X, unit). Unit X unit
%unroll unit : Unit (%self(X, unit). Unit X unit) unit
%self(A, u). (P : (A : Type) -> A -> Type) ->
P (%self(X, unit). Unit X unit) unit -> P A u
(P : (A : Type) -> A -> Type) ->
P (%self(X, unit). Unit X unit) unit -> P A u
unit : Unit = %unroll unit;
%self(Unit).
(unit : %self(a). Unit a a) ->
(u : %self(u). Unit unit u) -> Type
False = (f : Self) -> ()
False = %self(f). False f;
Self (x => )
%typeof M : %self(False). (f : %self(f). False f) -> Type
%self(Unit).
(unit : %self(a). Unit a a) ->
(u : %self(u). Unit unit u) -> Type
%fix
%self(Unit).
fix%Unit (u : Self) (unit : %typeof u) =
(P : (%self(u). %typeof u) -> Type) -> P unit -> P (%unpack u);
unit : %self(unit). Unit unit (%valueof unit) = _;
Unit = %self(u). Unit u unit;
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x). M : %self(A, x). T
Γ |- M : %self(A, x). T
-------------------------------------------
%unpack M : T[A := %self(A, x). T | x := M]
Γ |- M : %self(A, x). T
-------------------------------------------
%unfold M : T[A := %self(A, x). T | x := M]
Bool = T => (true : T) => F => (false : F) => %self(Bool, b).
Bool = T => (true : T) => F => (false : F) => %self(Bool, b).
(P : (A : Type) -> A -> Type) -> P T true -> P F false -> P Bool b;
// internal
UnitT = %self(Unit, u). (P : (A : Type) -> A -> Type) -> P Unit u -> P Unit u;
unit : UnitT = %fix(Unit, u). (P : (A : Type) -> A -> Type) => (x : P Unit u) => x;
Unit T (unit : T) (u : T) =
(P : T -> Type) -> P unit -> P (w Unit u);
fix%UnitW =
Unit UnitW ? ()
unit_ind
: (P : UnitT -> Type) -> P unit -> (u : Unit) -> P u
= P => p_unit => u =>
u (A => x => (A_eq_UnitT : A == UnitT) -> P (A_eq_UnitT (T => T) x))
(A_eq_UnitT => )
// external
unit : Unit = %unroll unit;
%self(Unit, u).
(P : (A : Type) -> A -> Type) -> P U unit -> P Unit u
(P : (A : Type) -> A -> Type) -> P U Unit -> P Unit U
Bool = T => (true : T) => F => (false : F) => %self(Bool, b).
(P : (A : Type) -> A -> Type) -> P T true -> P F false -> P Bool b;
true
: (F : Type) -> (false : F) -> %self(T, true). Bool T true F false
= F => false => %fix(T, true).
(P : (A : Type) -> A -> Type) => (then : P T true) => (else : P F false) => then;
false
: %self(F, false). Bool (%self(T, true). Bool T true F false) true F false
= %fix(F, false).
(P : (A : Type) -> A -> Type) => (then : P T true) => (else : P F false) => else;
Bool = Bool
(%self(T, true). Bool T true (%self(F, false). Bool T true F false) false) (true false)
(%self(F, false). Bool T true F false) false;
// setup
Bool : Type
true : Bool
false : Bool
Bool = %self(A, b). (P : (A : Type) -> A -> Type) -> P Bool true -> P Bool false -> P A b;
true = (P : (A : Type) -> A -> Type) => (then : P Bool true) => (else : P Bool false) => then;
false = (P : (A : Type) -> A -> Type) => (then : P Bool true) => (else : P Bool false) => else;
------------------------------------
(x : Bool) => x : (x : Bool) -> Bool
-------------------------------------------------
(A : Type) => (x : A) => x : (A : Type) -> A -> A
------------------------------
(A : Type) => A : Type -> Type
Bool = (A : Type) -> A -> A -> A;
------------------------------------------------------
(b : Bool) => (x : b Type Int String) => x
: (b : Bool) -> b Type Int String -> b Type Int String
Nat = (A : Type) -> A -> (A -> A) -> A;
ind : (P : Nat -> Type) -> P zero ->
((n : Nat) -> P n -> P (succ n)) -> (n : Nat) -> P n = ?;
f zero (p_zero) : P (succ zero)
case : (b : Bool) -> (A : Type) -> A -> A -> A = _;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b = _;
Bool = (P : Bool -> Type) -> P true -> P false -> P b?;
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x). M : %self(A, x). T
Γ |- M : %self(A, x). T
-------------------------------------------
%unroll M : T[A := %self(A, x). T | x := M]
False = %fix(False). %self(f). (P : False -> Type) -> P f;
(P : Nat ->)
fix%Unit (unit : %self(unit). Unit unit unit) (u : %self(u). Unit unit u) : Type
= (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
fix%unit : Unit unit unit =
(P : (%self(u). Unit unit u) -> Type) => (x : P unit) => x;
// keeping induction clean
%self(False). (f : %self(f). False f) -> Type
%self(Unit). (unit : %self(a). Unit a a) -> (%self(u). Unit unit u) -> Type
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x) : T. M : %self(A, x). T
(unit : %self(a). Unit a a)
Unit => %self(U, u). Unit U u u;
%self(False). (f : %self(f). False f) -> Type
%self(False). (A : Type) -> (f : %self(f). False f) -> Type
FalseT (ExternallyApply : (A : Type) -> A -> (((A : Type) -> A ->) -> Type) -> Type) =
%self(T, False). ExternallyApply T False
(False => A ->(f : %self(A, f). False A f) -> Type);
FalseT (T => False => A => f => )
fix%UnitT U1 (unit : U1) U2 (u : U2) =
(unit : %self(U, u). UnitT U u U u) ->
(u : %self(U, u). UnitT _ unit U u) ->
Type;
fix%Unit
(unit : %self(U, u). UnitT U u U u) U (u : U) : Type
= (P : (%self(U, u). Unit unit U u) unit U u) ->
Type) -> P unit -> P u;
fix%unit
%fix(A, Unit) : UnitT A Unit.
unit => u => (P : )
Unit = fix(A, Unit) : (unit : Unit) -> (u : Unit) -> Type.
(P : Unit unit u -> Type) -> P unit -> P u;
fix%Unit Unit (unit : Unit) U (u : U) : Type =
(P : );
False = A => f =>
(f : %self(A, f). False A f) -> Type;
False = A => f => False False
Unit =
(unit : %self(a). Unit a a) -> (%self(u). Unit unit u) -> Type
False = A => (f : A) =>
(P : A -> Type) -> P f
False = %fix(False) : (f : %self(f). False f) -> Type.
f => (P : (%self(f). False f) -> Type) -> P f;
False = %self(f). False f;
UnitT = %self(Unit, u). (P : (A : Type) -> A -> Type) -> P Unit u -> P Unit u;
unit : UnitT = %fix(Unit, u). (P : (A : Type) -> A -> Type) => (x : P Unit u) => x;
Unit : Type
unit : Unit
Unit = (P : Unit -> Type) -> P unit -> P unit;
Unit : Type
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
// expanded
Unit = %fix(Unit). (
unit = %fix(unit). (P : Unit -> Type) => (x : P unit) => x;
%self(u). (P : Unit -> Type) -> P unit -> P u
);
False = %fix(False). %self(f). (P : False -> Type) -> P f;
%fix(False). (P : False -> Type) -> P f
Unit : %self(Unit). (u : %self(u). Unit u). Type;
unit : %self(u). Unit u;
Unit = u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
unit = (P : (%self(u). Unit u) -> Type) => (x : P unit) => x;
Unit = %self(Unit). (unit : %self(u). Unit u) ->
fix%Unit (unit : %self(u). Unit u u) (u : %self(u). Unit u u) :Type.
(P : %self(u). Unit u u) -> P unit -> P u;
fix%unit : Unit unit unit = (P : %self(u). Unit u u) => (x : P unit) => x;
Unit = %self(u). Unit u u;
unit : Unit = unit;
unit : %self(u). Unit unit u;
%self(Unit).
(u : %self(u). Unit unit u) ->
(unit : %self(unit). Unit unit unit) -> Type
Unit : %self(Unit).
(unit : %self(unit). (u : %self(u). Unit unit (unit u)) -> Unit unit (unit u)) ->
(u : %self(u). Unit unit (unit u)) -> Type;
(u : %self(u). Unit unit (unit u)) -> Unit unit (unit u)
%self(unit). Unit unit (unit u)
expected : %self(u). Unit unit u
received :
Unit = %fix(Unit) : (unit : %self(unit). (u : ) Unit unit u) ->
(u : %self(u). Unit unit u) -> Type.
unit => u => (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
// WARNING: is this type well formed??? (%self(u). Unit u u) is weird
Unit : %self(Unit). (unit : %self(u). Unit u u) -> (u : %self(u). Unit unit u) -> Type
unit : %self(u). Unit u u;
Unit = unit => u => (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
unit = (P : (%self(u). Unit unit u) -> Type) => (x : P unit) => x;
// external
Unit = %self(u). Unit unit u;
unit : Unit = unit;
// expanded
Unit = %fix(Unit) : (unit : %self(u). Unit u u) -> (u : %self(u). Unit unit u) -> Type.
unit => u => (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
unit = %fix(unit) : Unit unit unit.
(P : (%self(u). Unit unit u) -> Type) => (x : P unit) => x;
// external
Unit = %self(u). Unit unit u;
unit : Unit = unit;
// WARNING: is this type well formed???
Unit : %self(Unit). (unit : %self(u). Unit u u) -> (u : %self(u). Unit unit u) -> Type
unit : %self(u). Unit u u;
Unit = unit => u => (P : (%self(u). Unit unit u) -> Type) -> P unit -> P u;
unit = (P : (%self(u). Unit unit u) -> Type) => (x : P unit) => x;
// external
Unit = %self(u). Unit unit u;
unit : Unit = unit;
Eq A x y = (P : A -> Type) -> P x -> P y;
Unit1 = %fix(Unit1). %self(u). (P : Unit1 -> Type) -> P u -> P u;
unit : Unit1 =
%fix(u). (P : Unit1 -> Type) => (x : P u) => x;
(P : Unit -> Type) -> P unit -> P unit
(P : Unit -> Type) -> P unit -> P unit
unit : %self(u). (P : Unit -> Type) -> P (%unroll u) -> P (%unroll u);
%unroll unit : %self(u). (P : Unit -> Type) -> P (%unroll u) -> P (%unroll u);
expected : %self(u). (P : Unit -> Type) -> P (%unroll unit) -> P u
%self(Unit).
(unit : %self(u). Unit u (%unroll u)) ->
(u : %self(u). Unit unit (%unroll u)) -> Type
%unroll unit : %self(u). Unit u u
%unroll unit : %self(u). Unit (%unroll unit) u
fix%Unit (unit : %self(u). Unit u u) (u : %self(u). Unit unit u) : Type =
(P : Unit -> Type) -> P
fix%Unit = %self(u). (K : Type) -> (Eq Unit u (%unroll unit) -> K) -> K;
fix%UnitT = %self(u). (K : Type) -> (Eq UnitT u u -> K) -> K;
fix%unit : UnitT = K => (k : (Eq Unit u u -> K)) => k refl;
fix%Unit = %self(u). (K : Type) -> (Eq Unit u (%unroll unit) -> K) -> K;
UnitT = %self(UnitT, u). (K : Type) -> (Eq UnitT u u -> K) -> K;
unit : UnitT = %fix(UnitT, u) => K => (k : Eq UnitT u u -> K) => k refl;
UnitT = %self(Unit, u). (K : Type) -> (Eq Type Unit Unit-> Eq Unit u u -> K) -> K;
unit : UnitT = %fix(Unit, u). (K : Type) => (k : Eq Unit u u -> K) => k refl;
Unit = %self(Unit, u). (K : Type) -> (Eq ->(P : (A : Type) -> A -> Type) -> P UnitT unit -> P Unit u;
ind (P : UnitT -> Type) (x : P Unit (%unroll unit)) (u : Unit) : P u =
u (A => x => (eq : A == UnitT) -> P A x eq)
Unit T (unit : T) (u : T) =
(P : T -> Type) -> P unit -> P (w Unit u);
%self(False). False // Type : Type
%self(A, False). False;
%self(A, False). (eq : A == ((eq : A == A) -> False)). eq (T => T) False;
%self(A, False). (eq : A == Type). eq (T => T) False;
Unit A unit u = (P : A -> Type) -> P unit -> P u;
unit = %fix(A, u) : Unit A u u. (P : A -> Type) => (x : P unit) => x;
Unit = %self(U2, u). Unit (%fix(U1, u). Unit U1 u U1 u) unit U2 u;
unit = (P : (%self(u). Unit u) -> Type) => (x : P unit) => x;
Unit U1 unit U2 u = (P : (A : Type) -> A -> Type) -> P U1 unit -> P U2 u;
U1 = %self(U1, u). Unit U1 u U1 u;
unit : U1 = %fix(U1, u). P => x => x;
Unit = %self(U2, u). Unit U1 unit U2 u;
// TODO: relies on removing duplicated self %self(A, x). %self(U2, u). T
unit = %unroll (A => x => %self(U2, u). Unit A x U2 u) unit;
Eq A x y = (P : A -> Type) -> P x -> P y;
refl A x : Eq A x x = P => x => x;
T1 = %self(T1, _). Eq Type T1 T1;
T2 = %self(T2, _). Eq Type T1 T2;
T2 = Eq Type
(%self(T1, _). Eq Type (%self(T1, _). Eq Type T1 T1) T1)
(%self(T1, _). Eq Type (%self(T1, _). Eq Type T1 T1) T1);
T2 = Eq Type (%self(T1, _). Eq Type (%self(T1, _). Eq Type T1 T1) T1) (%self(T1, _). Eq Type (%self(T1, _). Eq Type T1 T1) T);
T2 = Eq Type
(%self(T1, _). Eq Type (%self(T1, _). Eq Type T1 T1) T1)
(%self(T2, _). Eq Type (%self(T1, _). Eq Type T1 T1) T2);
// TODO: relies on removing duplicated self %self(A, x). %self(U2, u). T
unit = %unroll (A => x => %self(U2, u). Unit A x U2 u) unit;
Unit : Type;
T : (u : Unit) -> Type;
unit : Unit;
T = (u : Unit) => (P : Unit -> Type) -> P unit -> P u;
Unit = %self(u). T
%self(u). T
Unit = (unit : Unit) => (P : Unit -> Type) -> P unit
Unit U1 unit U2 u =
(P : (A : Type) -> A -> Type) -> P U1 unit -> P U2 u;
U1 = %self(U1, u). Unit U1 u U1 u;
unit : U1 = %fix(U1, u). P => x => x;
Unit = %self(U2, u). Unit U1 unit U2 u;
%self(U2, u). Unit U1 unit U2 u === %self(U1, u). Unit U1 unit U1 u
Unit A unit u = (P : A -> Type) -> P unit -> P u;
U1 = %self(U1, u). Unit U1 u u;
unit : U1 = %fix(U1, u). P => x => x;
U2 = %self(U2, u). Unit U2 unit u;
Unit u unit = (P : (%typeof u) -> Type) -> P unit -> P (%valueof u);
U1 = %self(u). Unit u (%valueof u);
unit : %self(u). Unit u (%valueof u) = %fix(u). P => x => x;
unit : %self(u). Unit u unit = %unroll unit;
Unit = %self(u). Unit u unit;
%fix(A, Sigma).
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x). M : %self(A, x). T
Γ |- M : %self(A, x). T
-------------------------------------------
%unpack M : T[A := %self(A, x). T | x := M]
Γ |- M : %self(A, x). T
-------------------------------------------
%unfold M : T[A := %self(A, x). T | x := M]
loop = %fix(f : Unit -> Unit). (x : Unit) => f x;
loop = %fix(A, f). (unfold : A -> Unit -> Unit) => (x : Unit) => unfold f x;
Eq A x B y = (P : (T : Type) -> T -> Type) -> P A x -> P B y
l = %fix()
%self(A, f). (unfold : A -> Unit -> Unit) -> Unit -> Unit;
Fix = %fix(Fix) : Type. (f : Fix) -> Unit;
fix : Fix = (f : Fix) => f f;
Fix = %fix(A, Fix).
(unfold : A -> Type) -> (f : unfold Fix) -> Unit;
fix = (f : Fix) => f ((x : Fix) => x);
Loop = %fix(Loop) : Type -> Type -> Type. A => B => A -> Loop B A;
Loop = %fix(A, Loop). A => B =>
Loop = %fix(A, Loop).
(unfold : A -> ) => A => B => A -> unfold Loop B A
fix = (f : Fix) => f f;
%self(Fix, _). (f : Fix) -> Unit
False = (f : Loop refl) => f refl;
Loop = %fix(A, Loop). (unfold : A -> Type) -> (f : Unit) -> unfold Loop;
False = (f : Loop) => f (x => x) () (x => x) ();
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x). M : %self(A, x). T
Fix = %fix(A, Fix). (unfold : A -> Type) => unfold Fix -> Unit;
fix = (f : Fix) => f (x => x) f;
False0 = %fix(A, False). (eq : A == Type) -> (f : eq (T => T) False) -> Unit;
False1 : Type = %unfold False;
%self(False). (f : %self(f). False f) -> Type
%fix(False) : (f : %self(f). False f) -> Type.
f => (P : (%self(f). False f) -> Type) -> P f;
//
Unit : %self(Unit). (u : %self(u). Unit u) -> Type;
unit : %self(u). Unit u;
Unit = u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
unit = (P : (%self(u). Unit u) -> Type) => (x : P unit) => x;
// steps, define both types, define Unit, define unit using definition of Unit
TUnit = %self(Unit). (u : %self(u). Unit u) -> Type;
MUnit (Unit : TUnit) (unit : Tunit Unit) =
u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
Munit (Unit : TUnit) (unit : Tunit)
= (P : (%self(u). Unit u) -> Type) => (x : P unit) => x;
expected : %self. \2 \1 \0
received : %self. \1 (%unroll \0) \0
expected : %self(u/1). Unit u/2 u/1
received : %self(u). Unit u u
//
(let ((fs (Y* ((f1 f2 ... fn) => e1) ... ((f1 f2 ... fn) => en))))
(apply ((f1 f2 ... fn) => e) fs))
Y (T : %self(T). (x : %self(x). T x) -> Type)
(w : (x : %self(x). T x) -> T x) : %self(x). T x = %fix(x) : T x. w x
Y* l =
(u => (u u))
(p => (map (li => x => li (p p) x) l))
fs = (Y* ((f1 f2 ... fn) => e1) ... ((f1 f2 ... fn) => en));
(apply ((f1 f2 ... fn) => e) fs))
%self(Unit). (unit : %self(u). Unit u u) -> (u : %self(u). Unit unit u) -> Type
// dependencies
Unit = %fix(Unit) : (u : %self(u). Unit u) -> Type.
u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
UnitT = %self(Unit). (u : %self(u). Unit u) -> Type;
Unit2 = %fix(Unit) : (unit : %self(u). Unit u) -> UnitT.
unit => MUnit (Unit unit) unit;
UnitX = %fix(Unit) : (unit : %self(u). Unit u) -> UnitT.
unit => (u : %self(u). Unit u) => (P : (%self(u). Unit u) -> Type) -> P unit -> P u) (Unit unit) unit;
Unit = (unit : %self(u). Unit u) =>
%fix(Unit) : (u : %self(u). Unit u) -> Type. MUnit Unit
T1 = %self(u). Unit u u;
%self(Unit).
(unit : %self(u). Unit u u) ->
(u : %self(u). Unit unit u) -> Type
expected : %self(u). Unit unit u
received : %self(u). Unit u u
Unit =
(f => x => f x x)
(x : Int 2) => x + x;
(G : Grade) -> Type;
(x : $Int) => (p : Bool)
(p | true => x + 1
| false => x) x;
f = (x : Int 2) => x + x;
abs : (A : Type) -> A = ?;
%self(Unit).
(self%unit : %self(u). Unit unit u) ->
(self%u : Unit unit u) -> Type
%self(False). (f : %self(f). False f) -> Type;
%self(T, False).
(unfold_T :
%self(UT, _). T -> (unfold_T : UT) -> (f : ) -> Type) ->
(f : %self(A, f). (unfold_A : A == ?) ->
unfold_T False unfold_T (unfold_A f)) -> Type
%self(False). (f : %self(f). False f) -> Type;
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
A = Γ, x : A |- T : Type A == T
----------------------------
Γ |- %self(x). T : Type
%exists ?X. %self(False) : (f : %self(f). _) -> Type.
(f : %self(f). False f) -> Type;
((A : Type 0) -> A -> A) : Type 1;
Type : Type
x => x;
id : (0 A : Prop) -> A -> A = A => x => x;
x = id ((0 A : Prop) -> A -> A);
1234567890
!@#$^&*()_
(x => ())
Γ, x : %self(x). T |- T : Type
------------------------------
Γ |- %self(x). T : Type
Γ, x : %self(x). T |- M : T
-----------------------------
Γ |- %fix(x). M : %self(x). T
case : Bool -> (A : Type) -> A -> A -> A = _;
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b = _;
Unit : %self(Unit). (unit : %self(unit). %self(u). Unit unit u) -> (u : %self(u). Unit unit u) -> Type;
unit :%self(unit). %self(u). Unit unit u
u : %self(u). Unit unit u;
Unit : %self(Unit). _A
%self(False). (f : %self(f). False f) -> Type
False : %self(False). _A
f : %self(f). _B
_A := (f : %self(f). _B) -> Type
_B := False f
unify (%self(False). _A) (%self(False). (f : %self(f). False f) -> Type)
unify (%self(False). (f : %self(f). False f) -> Type) (%self(False). (f : %self(f). False f) -> Type)
Unit : %self(Unit). (unit : %self(unit). %self(u). Unit unit u) -> (u : %self(u). Unit unit u) -> Type;
%self(Unit). (unit : %self(unit). %self(u). Unit unit u) -> (u : %self(u). Unit unit u) -> Type;
Bool = %self(b). (P : Bool -> Type) -> P true -> P false -> P b;
(x => x(x))(x => x(x))
(x => x(x))(x => x(x))
(x => x(x))(x => x(x))
f () = f ()
f = (x => x(x));
g = (x => x(x));
true_ = x => y => x;
false_ = x => y => y;
if_ = b => x => y => b(x)(y);
if_(true_)(0)(1)
Kind =
| *
| K -> K;
Type =
| A -> B
| <A : K>B
| A<B>;
Term =
| x
| (x : T) => m
| m n
| <A>m;
| m<A>;
id : (x : Int) -> Int = (x : Int) => x;
incr : (x : Int) -> Int = (x : Int) => x + 1;
zero = z => s => z;
succ = n => z => s => s(n(z)(s));
one = z => s => s(z);
two = z => s => s(s(z));
two = succ(succ(zero));
Bool = <A>(x : A) => (y :)
true : = x => y => x;
false : = x => y => y;
(x : Int) -> Int
Int implies Int;
<A>(x : A) -> A
<A>(x : A) => A;
Forall A, A implies A;
(<A>(x : A) -> A)<Int>
(x => m)(n) === m[x := n];
(<A>m)<B> === m[A := B];
(<A>(x : A) => x)<Int>
((x : A) => x)[A := Int]
(x : Int) => x
(x : Int) =>
(x : Int) =>
(<A>((x : A) => x))<Int>
Int : *
(<F : * -> * >F<Int>)
T : * -> *
Term -> Term // Simply Typed Lambda Calculus // Functions
Type -> Term // System F // Parametric Polymorphism
Type -> Type // System Fω // Higher Kinded Type
Term -> Type // Calculus of Construction // Dependent Types
Id : Type = (A : Type) -> A -> A;
id : Id = (A : Type) => (x : A) => x;
Bool = (A : Type) -> A -> A -> A;
true : Bool = (A : Type) => (x : A) => (y : A) => x;
false : Bool = A => x => y => y;
A -> B
f : (x : Bool) -> x Type Int String -> x Type Int String
= (x : Bool) => (y : x Type Int String) => y;
f : (x : Bool) -> x Type Int String -> x Type Int String
= (x : Bool) => (y : x Type Int String) => y;
a : Int -> Int = f true;
b : String -> String = f false;
| Rust |
| OCaml | TypeScript |
| Elixir | Haskell | C# | C | Python | Lua |
| Scala | F# | Go | Java | PHP | Clojure | Ruby | JavaScript | C++ | Perl |
@Unit -> (unit : @unit -> @u -> (@Unit) unit u) -> (u : @u -> (@Unit) unit u) -> Type
@(Unit : @Unit -> (unit : @unit -> @u -> (@Unit) unit u) -> (u : @u -> (@Unit) unit u) -> Type) =>
(unit : @unit -> @u -> (@Unit) unit u) => (u : @u -> (@Unit) unit u) =>
(P : (u : @u -> (@Unit) unit u) -> Type) -> P (@unit) -> P u
@(False : @False -> (f : @f -> False@ f) -> Type) => (f : @f -> False@ f) => (P : (f : @f -> False@ f) -> Type) -> P f
@A : (f : @f -> @A f) -> Type
f : expected = term : received
term : expected
unit = %fix(unit).
%fix(u) : (eq :
%self(eq).
(P : Unit (unit u eq) (u eq) -> Type) -> P (unit u eq) -> P (u eq);
) -> Unit (unit u eq) (u eq).
(P : (%self(u). Unit (unit u eq) u) -> Type) => (x : P (unit u eq)) =>
eq P x;
%self(unit). %self(u). Unit unit u;
expected : %self(u). Unit unit u
received : %self(u). () -> Unit unit (u ())
%fix(unit) : -> W (%self(u). Unit unit u).
%fix(u) : (self%eq : unit u eq == u eq) -> Unit (unit u eq) (u eq).
eq => (P : (%self(u). Unit (unit u eq) u) -> Type) => (x : P (unit u eq)) => eq P x;
%self(Unit).
(unit : %self(unit). %self(u). Unit unit u) ->
(u : %self(u). Unit unit u) -> Type;
%self(Unit).
(unit : %self(unit) Unit unit unit) ->
(u : %self(u). Unit unit u) -> Type;
// TODO: those should be equal
%self(unit). %self(u). Unit unit u ===
%self(unit). Unit unit unit
Γ |- M : T[x := M]
-------------------------------
%roll(M) <== %self(x). T
Γ |- M : %self(u : A). B
-------------------------------
%unroll(M) : B[u := %unroll(M)]
Γ |- M : A
-------------------------------
M@ <== %self(x). B
%self(x). Int <> Int
T : %self(T). (a : %self(b). T b b) -> (c : %self(d). T a d) -> Type;
%self(T). (e : %self(f). T f f) -> (g : %self(h). T a d) -> Type
// %self(unit). %self(u). Unit unit u
CoC + Self Types
%self(Unit).
(unit : %self(unit). %self(u). Unit unit u) ->
(u : %self(u). Unit unit u) -> Type;
(unit : %self(unit). %self(u). Unit unit u) => Unit unit unit
%self(Unit).
(unit : %self(unit) Unit unit unit) ->
(u : %self(u). Unit unit u) -> Type;
data%Bool = | true | false;
data%Nat = | zero | succ (n : Nat);
Type : Type
// functions
Γ, x : A |- B : Type
--------------------
(x : A) -> B : Type
Γ, x : A |- m : B
---------------------------
(x : A) => m : (x : A) -> B
Γ |- m : (x : A) -> B Γ |- n : A
----------------------------------
m n : B[x := n]
// induction
Γ, x : @x -> T |- T : Type
----------------------
@x -> T : Type
Γ, x : @x -> T |- m : T
-----------------------
@x : T => m : @x -> T
%self(Unit). (unit : %self(unit). Unit unit (%coerce unit : %self(u). Unit unit u)) ->
(u : %self(u). Unit unit (%coerce u : %self(u). Unit unit u)) -> Type;
%self(Unit). (a : %self(b). Unit b (%coerce b : %self(u). Unit b u)) ->
(c : %self(d). Unit a (%coerce d : %self(u). Unit a u)) -> Type;
received : %self(a). Unit b a
expected : %self(a). Unit b (%coerce a : %self(u). Unit b u)
%self(Unit).
(u : %self(u). Unit (%coerce (%unroll u))) -> Type;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%False (f : %self(f). False f) =
(P : (%self(f). False f) -> Type) -> P f;
Unit = unit => %fix(Unit). (u : %self(u). Unit u) =>
(P : (%self(u). Unit u) -> Type) -> P unit -> P u;
Unit = unit => u => %fix(Unit).%self(u). (P : ? -> Type) -> P unit -> P u;
%self(u). (%fix(Unit). (unit : %self(unit). Unit unit) =>
(P : Unit unit -> Type) -> P unit -> P u) (%fix(unit). P => x => x);
%self(Unit). (unit : %self(unit). Unit unit (%unroll unit)) ->
(u : Unit unit (%unroll unit)) -> Type;
fix%Unit (unit : %self(unit). Unit unit (%unroll unit)) (u : Unit unit (%unroll unit)) =
(P : Unit unit (%unroll unit) -> Type) -> P (%unroll unit) -> P u;
fix%unit : Unit unit (%unroll unit) =
(P : Unit unit (%unroll unit) -> Type) => (x : P (%unroll unit)) => x;
%self(Unit). (unit : %self(unit). Unit unit (%unroll unit)) ->
(u : Unit unit (%unroll unit)) -> Type;
W u == (P : (%self(u). W u) -> Type) -> P unit -> P unit
Unfold (Unit : Type) (unit : Unit) =
%self(I). (%self(u). (P : Unit -> Type) -> P unit -> P (I u)) -> Unit;
MKUnit (Unit : Type) (unit : Unit) (I : Unfold Unit unit) =
%self(u). (P : Unit -> Type) -> P unit -> P (I u);
fix%Unit
(unit : %self(unit). (unfold : %self(unfold). Unfold (Unit unit unfold) (%unroll unit)) -> Unit unit unfold)
(unfold : %self(unfold). Unfold (Unit unit unfold) (%unroll unit))
= MKUnit (Unit unit unfold) ((%unroll unit) unfold) unfold;
fix%Unit0
(I : %self(I). (unit : %self(unit). Unit0 I unit) ->
(%self(u). (P : Unit0 I unit -> Type) -> P (%unroll unit) -> P (I unit u)) -> Unit0 I unit)
(unit : %self(unit). Unit0 I unit)
= %self(u). (P : Unit0 I unit -> Type) -> P (%unroll unit) -> P (I unit u);
fix%Unit0
(I : %self(I). (unit : %self(unit). Unit0 I unit) ->
(%self(u). (P : Unit0 I unit -> Type) -> P (%unroll unit) -> P (I unit u)) -> Unit0 I unit)
(unit : %self(unit). Unit0 I unit)
= %self(u). (P : Unit0 I unit -> Type) -> P (%unroll unit) -> P (I unit u);
Unit1 = Unit0 (%fix(I). unit => x => x);
unit => (P : Unit1 unit -> Type) => (x : P (%unroll unit)) => I P x
unit = %fix(unit). %fix(u). (P : Unit1 unit -> Type) => (x : P (%unroll u)) => (x : P u)
%self(unit). %self(u). (P : Unit1 unit -> Type) -> P (%unroll unit) -> P u
%self(unit). %self(u). (P : Unit0 I unit -> Type) -> P (%unroll unit) -> P u
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u)
= (P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll unit)
MKUnit = (Unit : Type) => (unit : Unit) =>
(unfold : %self(unfold). (%self(u). (P : Unit -> Type) -> P unit -> P (unfold u)) -> Unit) =>
%self(u). (P : Unit -> Type) -> P unit -> P (unfold u);
fix%Unit (unit : %self(unit). Unit unit) = MKUnit (Unit unit) unit
fix%Unit0 =
Unit = MK (%self(u). Unit
%self(unit).
fix%unit
: (P : (%self(u). W u) -> Type) -> P unit -> P unit
= P => x => x;
fix%Unit (u : %self(u). Unit u) =
(P : (%self(u). Unit u) -> Type) -> P (
%fix(unit) : (P : (%self(u). Unit u) -> Type) -> P (%fix(unit). unit ) -> P u. unit
) -> P u;
Unit = %self(u). Unit i (%unroll u);
unit : Unit = unit;
u : %self(u). (%fix(Unit). (unit : %self(unit). Unit unit) =>
(P : Unit unit -> Type) -> P unit -> P u) (?);
u : %self(u). (P : ((%fix(Unit). (unit : %self(unit). Unit unit) =>
(P : Unit unit -> Type) -> P unit -> P u)) (%fix(unit). P => x => x) -> Type) -> P (%fix(unit). P => x => x) -> P u ;
%self(unit). Unit unit (%unroll unit);
received : %self(unit). %self(u). Unit unit u
expected : %self(unit). %self(u). Unit unit u
%self(u). Unit unit (%roll u)
%self(Unit). (unit : %self(unit). Unit unit (%coerce unit : %self(u). Unit unit u)) ->
(u : %self(u). Unit unit u) -> Type;
received : %self(unit). Unit unit (%coerce unit : %self(u). Unit unit u)
expected : %self(u). Unit unit u
(unit : %self(unit). %self(u). Unit unit u) -> Unit unit (%unroll unit)
f = (unit : %self(unit). %self(u). Unit unit u) =>
(P : (%self(u). Unit unit u) -> Type) => (x : P (%unroll unit)) => x;
%fix(unit). f unit
%self(unit). Unit (%coerce unit) unit;
received : Unit (%coerce unit) unit
expected : Unit unit unit
fix%unit : Unit (%roll unit) unit
%self(Unit). (unit : %self(unit). Unit unit unit) ->
(u : %self(u). Unit unit u) -> Type
fix%Unit (unit)
main = print("Hello World");
fun x.
all x.
self x.
fix x.
((x : Int) => x)
((x : String) => x)
m : Nat -> Type
n : Int -> Type
(m x)
(n (coerce x))
fix%Fix = Fix -> Fix;
(a : Nat 1) => (b : Nat 1) => Nat 1
(x) => x + x
(f : Fix * 4) => f f;
(1 obj) =>
fix%False (I : %self(I). (%self(f). (P : False I -> Type) -> P (I f)) -> False I)
= %self(f). (P : False I -> Type) -> P (I f);
False = False (%fix(unfold). (x ) => (x));
I : %self(I). (unit : %self(unit). (I : ?) Unit1 unit I unit) -> %self(u). Unit0 I u;
Unit0T (T : Type) = %self(Unit0).
(I : T -> %self(u). Unit0 I u) -> (u : %self(u). Unit0 I u) -> Type;
%self(Unit1). (unit : %self(unit). (I : %self(I). Unit1 unit I unit -> %self(u). Unit1 unit I u) -> Unit1 unit I unit) ->
%self(Unit0). (I : ? -> %self(u). Unit0 I u) -> (u : %self(u). Unit0 I u) -> Type;
Unit0 (Unit : Type) (unit : Unit) (u : Unit) =
(P : Unit -> Type) -> P unit -> P u;
%fix(Unit). (unit : %self(unit). Unit unit unit) => (u : %self(u). Unit unit u) =>
%self(False). (f : %self(f). False (%coerce f : ?)) -> Type;
%self(False). (f : %self(f). False (%coerce f : ?)) -> Type;
%self(f). False (%coerce f : %fix(T). %self(f). False (%coerce f : T))
%self(Unit). (
(u : %self(u). Unit unit u)
)
%fix(Unit). (unit : %self(unit). Unit unit (%coerce unit : )) =>
(u : %self(u). Unit unit u) =>
%fix(Unit2). unit => %fix(Unit1). u =>
Unit0 ? unit u;
%fix(Unit2). (unit : %self(unit). (I : IT) -> Unit2 unit I (unit I)) =>
%fix(Unit1). (I : %fix(IT). %self(I). (%self(unit). (I : IT) -> Unit2 unit I (unit I)) -> %self(u). Unit1 I u) =>
(u : %self(u). Unit1 I u) => Unit0 (%self(u). Unit1 I u) (I unit) u;
fix%unit1 : Unit1 unit0 unit0 =
(P : )
fix%Unit1 (Unit : Type) (unit : Unit) (I : %self(I). Unit -> %self(u). Unit1 Unit unit I u)
(u : %self(u). Unit1 Unit unit I u) : Type =
Unit0 (%self(u). Unit1 Unit unit I u) (I unit) u;
Unit1 (Unit : Type) (unit : Unit)
(I : %self(I). (%self(u). Unit0 Unit unit (I u)) -> Unit) : Type =
%self(u). Unit0 Unit unit (I u);
fix%Unit2 (unit : (I : ?) -> %self(unit). Unit0 (Unit2 unit))
= Unit1 (Unit2 unit I) (unit I)
Unit1 (Unit : Type) (unit : Unit)
(I : %self(I). (Unit0 Unit unit (I u)) -> Unit) : Type =
Unit0 Unit unit (I u);
fix%Unit2 (unit : %self(unit). Unit1 unit I) (I : %self(I). Unit -> %self(u). Unit1 Unit unit I u)
(u : %self(u). Unit1 Unit unit I u) : Type =
Unit0 (%self(u). Unit1 Unit unit I u) (I unit) u;
%fix(Unit1). (I : %self(I). ? -> %self(u). Unit1 I u) => (u : %self(u). Unit1 I u) =>
Unit0 (%self(u). Unit1 I unit u) (I unit) u;
fix%Unit0 (Unit : Type) (I : %self(I). Unit -> %self(u). Unit0 Unit I unit u)
(unit : Unit) (u : %self(u). Unit0 Unit I unit u)
= (P : (%self(u). Unit0 Unit I unit u) -> Type) -> P (I unit) -> P u;
fix%Unit1
(I : %self(I). (%self(u). Unit1 I u) -> %self(u). Unit0 Unit I unit u)
(unit : %self(unit). Unit1 I unit)
= %self(u). Unit0 (%self(u). Unit1 I u) I unit u;
expected : %self(u). Unit0 Unit I unit u
fix%Unit1 (Unit : Type) (unit : Unit)
(I : %self(I). Unit -> %self(u). Unit0 I u) (u : %self(u). Unit0 I u)
= (P : (%self(u). Unit0 I u) -> Type) -> P (I unit) -> P u;
%fix(Unit1). (unit : %self(unit). (I : ? -> %self(u). Unit1 unit I u) -> Unit1 unit I unit) =>
%fix(Unit0 : Unit0T). I => u =>
(P : (%self(u). Unit0 I u) -> Type) -> P (I unit) -> P u;
Unit1 = Unit0 (%fix(I). unit => x => x);
(x => z) => x;
fix%False (I : %self(I). (%self(f). (P : False I -> Type) -> P (I f)) -> False I)
= %self(f). (P : False I -> Type) -> P (I f);
False = False (%fix(I). x => x);
received : %self(unit). %self(u). (P : Unit I -> Type) -> P (I (%unroll unit)) -> P (I u)
expected : %self(u). (P : Unit I -> Type) -> P (I (%coerce unit)) -> P (I u)
%self(unit). %self(u). (P : Unit I -> Type) -> P (I (%unroll unit)) -> P (I u)
Unit0 (Unit : Type) (unit : Unit) (u : Unit) =
(P : Unit -> Type) -> P unit -> P u;
%self(u). (I1 : -> T) ->
(I0 : %self(I0). -> T) ->
Unit0 T (I1 unit) (I0 u))
%fix(u). (P : T -> ) => ()
%self(Unit). (I : %self(I). ((
unit : %self(unit). (P : Unit I -> Type) -> P (I unit) -> P (I unit) = _;
%self(u). (P : Unit I -> Type) -> P (I unit) -> P (I u)
) -> Unit I))
-> Type;
fix%Unit (I : %self(I). (%self(u). (P : Unit I -> Type) ->
P (I (%fix(unit) : (P : Unit I -> Type) -> P (I unit) -> P (I unit). P => x => x)) -> P (I u)
) -> Unit I)
= %self(u). (P : Unit I -> Type) ->
P (I (%fix(unit) : (P : Unit I -> Type) -> P (I unit) -> P (I unit). P => x => x)) -> P (I u);
fix%Unit (I : %self(I). (u : %self(u). Unit I u) -> Unit I u) (u : %self(u). Unit I u) =
(P : (%self(u). Unit I u) -> Type) -> P (%fix(u) : Unit I u. I (P => x => x)) -> P u;
%fix(u). (I : %self(I). ) =>
(P : (%self(u). Unit I u) -> Type) => (x : P u) => (x : P u)
Unit1 = Unit (%fix(I). u => k => (x : P (%fix(u) : Unit I u. I u)) => ?)
fix%Unit (I : %self(I). (u : %self(u). Unit I u) -> Unit I u) (u : %self(u). Unit I u) =
(P : (%self(u). Unit I u) -> Type) -> P (%fix(u) : Unit I u. I u) -> P u
Unit1 = Unit (%fix(I). u => P => (x : P (%fix(u) : Unit I u. I u)) => ?)
(P : (%self(u). Unit I u) -> Type) -> P (%fix(u) : Unit I u. I (%fix(unit). P => x => x)) -> P unit
False = False (%fix(I). x => x);
This tries to avoid internal expansion of fixpoint but still achieve induction for Unit.
Fails to type check due to some weird behaviour.
%self(Unit). (unit : %self(unit). Unit unit unit) =>
(u : %self(u). Unit unit u) -> Type
fix%Unit (I : ?) (u : %self(u). Unit I u) =
(P : (%self(u). Unit I u)) -> P (%fix(u) : Unit I u. I u) -> P u;
How to scale this to unit?
fix%False (I : %self(I). (%self(f). (P : False I -> Type) -> P f) -> False I) =
%self(f). (P : False I -> Type) -> P f;
False = False (%fix(I). x => x);
How to build the constructor?
%self(Unit). (unit : %self(unit). %self(u). Unit unit u) ->
(u : %self(u). Unit unit u) -> Type
Seems natural if you try to lift first u
then unit
.
%self(Unit1). (unit : ?) -> %self(Unit0). (u : ?) -> Type
%fix(Rec). Rec -> ();
RecT = %self(RecT, Rec). (I : %self(B, I). B -> RecT -> Type) -> Type;
Rec : RecT = %fix(A, Rec). I => I I Rec -> ();
I = %fix(B, I). (I : B) => (Rec : RecT) => Rec I;
%fix(False). (f : False) => (P : False -> Type) -> P f
False = %fix(FalseT)
(Rec I -> ());
%self(False). (f : %self(f). False f) -> Type;
%self(FalseT, False).
(I : %self(IT, _). FalseT -> (f : ?) -> Type) ->
(f : %self(fT, f). I False I) -> Type;
Why does this works?
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, x : A |- B : Type A === B[]
----------------------------------
%self(x : A). B : Type
Γ, x : A |- B : Type A === B[x := ]
--------------------------------------------------
%self(x : A). B : Type
%self(False). (f : %self(f). False f) -> Type
%self(KFalse, False : (f : %self(Kf, f). KFalse f)).
(f : %self(f). False f) -> Type
T : Type = %fix(False : Type). (f : False) -> (P : False -> Type) -> P f;
%fix(False : T). (f : False) ->
(P : False -> Type) -> P
%self(T, False). (I : T -> Type) -> (f : I False) -> Type;
False = %fix(T, False : Type) : (I : T -> Type) -> (f : I False) -> Type.
(I : T -> Type) => (f : I False) =>
(P : I False -> Type) -> P f;
False = False (False => )
%self(T, False). (f : )
((F : Type) => (False : F -> Type) => (f : F) => False f);
%self(F, f). I F False f
%self(FalseT, False). (f : %self(f). False f) -> Type
False = %self(False. f). (P : False -> Type) -> P f;
-----------
Self : Type
Γ |- M : Self
----------------
%typeof M : Type
Γ |- M : Self
----------------------
%unpack M : %typeof M
Γ, x : Self |- T : Type
-----------------------
%self(x). T : Type
Γ, x : %self(x). T : T
----------------------
%self(x). T : Type
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
Γ |- M : %self(A, x). T
-------------------------------------------
%unroll M : T[A := %self(A, x). T | x := M]
%self(False). (I : Self -> Self -> Type) ->
(f : %self(f). I False f) -> Type;
%self(f). (P : False I -> Type) -> P (I f);
unit = P => (x : P unit) => x
%self(A, x). T
Γ, x : A |- B : Type
----------------------
%self(x : A). B : Type
Γ, x : A |- M : B
--------------------------------
%fix(x : A). M : %self(x : A). B
Γ |- M : %self(x : A). B
------------------------
%unroll M : T[x := M]
%self(False).
%self(x : A). B
%self(Unit).
(a : %self(b). Unit b b) ->
(c : %self(d). Unit a d) -> Type;
%self(Unit).
(a : %self(b). (? : (%self(d). Unit a d) -> Type) b) ->
(c : %self(d). Unit a d) -> Type;
%self(Unit). (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type;
%self. (%self. %unroll 1 0 0) -> (%self. %unroll 2 1 0) -> Type
%self. %unroll (1 : %self. (%self. %unroll 1 0 0) -> (%self. %unroll 2 1 0) -> Type) 0 0
%self. (%unroll 1 : (%self. %unroll 2 0 0) -> (%self. %unroll 3 1 0) -> Type) 0 0
%self. (%unroll 1 0 : (%self. %unroll 2 0 0) -> Type) 0 0
%self. (%self. ((1 0 : ) 0) -> (%self. 2 1 0) -> Type
received : %self. 1 0 0
expected : %self. 2 1 0
(λ.0) 1 === 1
%self(b). Unit b b
%self(d). Unit b d
%self(b). Unit b b
%self(d). Unit a d
%self(unit). Unit unit unit
%self(u). Unit unit u
%self(unit). (P : ? -> Type) -> P unit -> P unit;
%self(unit). (P : ? -> Type) -> P (%fix(unit). P => (x : P unit) => x) -> P unit;
%self(u). (P : ?) -> P u -> P u
Unit = %fix(Unit).
(P : Unit -> Type) -> P (%fix(unit). P => (x : P unit) => x)
%self(Unit). (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type;
%self(b). %unroll (Unit : %self(Unit). (e : %self(f). %unroll Unit f f) -> (g : %self(h). %unroll Unit e h) -> Type) b b
%self(b). (%unroll Unit : (e : %self(f). %unroll Unit f f) -> (g : %self(h). %unroll Unit e h) -> Type) b b
%self(b). (%unroll Unit (b : %self(b). %unroll Unit b b) : (g : %self(h). %unroll Unit b h) -> Type) b
received : %self(b). %unroll Unit b b; %unroll Unit i i
expected : %self(h). %unroll Unit b h; %unroll Unit i i // replaced b := i here
%self(b). (%unroll Unit b b : Type)
%self. %unroll (1 : %self. (%self. %unroll 1 0 0) -> (%self. %unroll 2 1 0) -> Type) 0 0
%self. (%unroll 1 : (%self. %unroll 2 0 0) -> (%self. %unroll 3 1 0) -> Type) 0 0
%self. (%unroll 1 (0 : %self. %unroll 2 0 0) : (%self. %unroll 2 0 0) -> Type) 0
%self. (%unroll 1 0 : (%self. %unroll 2 0 0) -> Type) (0 : %self. %unroll 2 0 0)
%self. (%unroll 1 0 0 : Type)
%self(Unit). (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type;
fix%Unit (unit : %self(unit). %unroll Unit unit unit) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P unit -> P u;
fix%unit : %unroll Unit unit unit = P => x => x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = unit;
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
fix%Unit (unit : %self(unit). %unroll Unit unit unit) (u : %self(u). %unroll Unit unit u)
= (P : (u : %self(u). %unroll Unit unit u) -> Type) -> P unit -> P u;
fix%unit : %unroll Unit unit unit = P => x => x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = unit;
ind (u : Unit) = %unroll u;
%fix(Unit)
Unit : %self(Unit).
(unit : %self(unit). %unroll Unit unit unit) ->
(u : %self(u). %unroll Unit unit u) -> Type
received : %self(k). %unroll Unit k k // unit := k; u := k
expected : %self(k). %unroll Unit k k // unit := k; u := k
%self. (%self. %unroll 1 0 0) -> (%self. %unroll 2 1 0) -> Type
%self. %unroll (1 : %self. (%self. %unroll 1 0 0) -> (%self. %unroll 2 1 0) -> Type) 0 0
%self. (%unroll 1 : (%self. %unroll 2 0 0) -> (%self. %unroll 3 1 0) -> Type) 0 0
%self. (%unroll 1 (0 : %self. %unroll 2 0 0) : (%self. %unroll 2 0 0) -> Type) 0
%self. (%unroll 1 0 0 : Type)
fix%Unit (self%unit : %unroll Unit unit unit) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P unit -> P u;
fix%unit : %unroll Unit unit unit = P => x => x;
@Unit (@unit : @Unit unit unit) (@u : @Unit unit u) : Type =
(P : (@u : @Unit unit u) -> Type) -> P unit -> P u;
Unit = u @-> Unit unit u;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = unit;
@>
%self(f). (x) => x
@f. (x) => x
@f(x) => x
λa. λb. b === λc. λd. d
λa. λb. a === λc. λd. c
λλ0 === λλ0 1 2
λλ1 === λλ1
formation : (x : Int) -> Int
introduction : (x : Int) => x
elimination : lambda arg
formation : %self(x). T
introduction : %fix(x) : T. m
elimination : %unroll x
%fix(0 Rec). (n : Rec) -> Int
%self(x, y). (x : Int, y : Int)
Int ->! Int;
(x => x(x)) : %fix(0 Rec). (1 : Rec) -> Int;
%self(False). (f : %self(f). False f) -> Type;
(%fix(x) : T. (m : T)) : %self(x). T
%fix(x : T). m
((x : %fix(Rec). Rec -> Int) => (%unroll x)(x))
%fix(x) : T. x
let rec f x = x + f x
let f = fun self x -> x + self x
let f = %fix(self). f self;
- -> +
%fix(Rec). Rec -> Int
fold : Nat -> (A : Type) -> A -> (A -> A) -> A;
case : Nat -> (A : Type) -> A -> (Nat -> A) -> A;
Nat = (A : Type) -> A -> (Nat -> A) -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = (P : (0 Bool) -> Type) -> P true -> P false -> P b;
b => (P : Bool -> Type) -> P true -> P b;
%fix(Rec). (0 Rec) -> Int
((0 x : %fix(Rec). (0 Rec) -> Int) => 1)
Type : Type
((A : Type) -> A) : Type
(A : Type) => (x : A) => x;
(x => y => y)
(a => b => b)
f ((x : Int) => x)
f ((y : Int) => y)
Unit @-> (unit : unit @-> Unit unit unit) @-> (u @-> Unit unit u) -> Type
received : unit @-> Unit unit unit
expected : u @-> Unit unit u
Array.set : Array<A> -> Int -> A -> Array<A>;
f = (arr : Array<Int>) => (
arr = Array.set(arr, 0, 0);
arr = Array.set(arr, 1, 1);
);
Array.set : &mut Array<A> -> Int -> A -> ();
f = (arr : Array<Int>) => (
Array.set(arr, 0, 0);
Array.set(arr, 1, 1);
);
f : () -> Int;
f() === f();
incr = x => x + 1;
incr 1 === (x => x + 1) 1;
acc = 0;
f = () => acc;
x = f
double = (x : User) => (
let () = free(x);
1
);
(x => x + x)
x.y := x;
Socket : Type;
connect : () -> Socket;
close : Socket -> ();
f = () => (
socket = connect();
close(socket);
1
)
f : %self(False). (f : %self(f). False f (x => x)) -> (k : Int -> Int) Type;
False :
(f : %self(f). False f) -> Type
(f : %self(f). %unroll False f) -> Type
P Int ((x : Int) => x)
P Bool ((x : Bool) => x)
(x : Int) -> Int
Rank-2 allows for existential types. Infinite rank-1 instances.
Maybe some polymorphic recursion thing?
It only allows for one instance, so is it isomorphic to just having monomorphized signatures?
Can you always monomorphize rank-2 polymorphism?
@False (@f : False f) = (P : (@f : False f) -> Type) -> P f;
False @=> (@f : False f) => (P : (@f : False f) -> Type) -> P f;
False @=> (@f : (False @=> (@f : False f) => (P : (@f : False f) -> Type) -> P f) f) => (P : (@f : False f) -> Type) -> P f;
False : False @-> (f : f @-> @False f) -> Type ===
((False : False @-> (f : f @-> @False f) -> Type) @=>
(f : f @-> @False f) => (P : (f : f @-> @False f) -> Type) -> P f);
False
%self(False). (f : %self(f). False f) -> Type
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
fix%Unit (a : %self(b). %unroll Unit b b) (c : %self(d). %unroll Unit a d) =
(P : (e : %self(f). %unroll Unit a f) -> Type) -> P a -> P c;
%self(Unit). (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type;
%fix. (%self. %unroll \1 \0 \0) => (%self. %unroll \2 \1 \0) =>
((%self. %unroll \3 \2 \0) -> Type) -> \0 \2;
%fix. (%self. %unroll \1 \0 \0) => (%self. %unroll \2 \1 \0) =>
((%self. %unroll \3 \2 \0) -> Type) -> \0 \2;
((\0 : (%self. %unroll \4 \3 \0) -> Type) (\2 : %self. %unroll \4 \0 \0))
fix%Unit
(I : %self(I). (unit : %self(unit). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit unit)) ->
(u : %self(u). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit u)) -> %unroll Unit I unit)
(unit : %self(unit). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit unit)) =
%self(u). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit u);
%self(Unit).
(I : %self(I). (unit : %self(unit). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit unit)) ->
(u : %self(u). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit u)) -> %unroll Unit I unit) ->
(unit : %self(unit). (P : %unroll Unit I unit -> Type) -> P (I unit unit) -> P (I unit unit)) -> Type;
%self(Unit).
(A : %self(B). (c : %self(d). (P : %unroll Unit B d -> Type) -> P (B d d) -> P (B d d)) ->
(e : %self(f). (P : %unroll Unit B c -> Type) -> P (B c c) -> P (B c f)) -> %unroll Unit B c) ->
(g : %self(h). (P : %unroll Unit A h -> Type) -> P (A h h) -> P (A h h)) -> Type;
%self(B). (c : %self(d). (P : %unroll Unit B d -> Type) -> P (B d d) -> P (B d d)) ->
(e : %self(f). (P : %unroll Unit B c -> Type) -> P (B c c) -> P (B c f)) -> %unroll Unit B c
expected : %self(f). %unroll Unit a f
received : %self(b). %unroll Unit b b
Unit @->
(I : I @-> (unit : unit @-> (P : (u : @Unit I unit) -> Type) -> (x : P (@I unit unit)) -> P (@I unit unit)) ->
(u : u @-> (P : (u : @Unit I unit) -> Type) -> (x : P (@I unit unit)) -> P (@I unit u)) -> @Unit I unit) ->
(unit : unit @-> (P : (u : @Unit I unit) -> Type) -> (x : P (@I unit unit)) -> P (@I unit unit)) -> Type
Unit @->
(A : B @-> (c : d @-> (P : (u : @Unit B d) -> Type) -> (x : P (@B d d)) -> P (@B d d)) ->
(e : f @-> (P : (g : @Unit B c) -> Type) -> (x : P (@B c c)) -> P (@B c f)) -> @Unit B c) ->
(h : i @-> (P : (l : @Unit A i) -> Type) -> (x : P (@A i i)) -> P (@A i i)) -> Type
B @-> (c : d @-> (P : (u : @Unit B d) -> Type) -> (x : P (@B d d)) -> P (@B d d)) ->
(e : f @-> (P : (g : @Unit B c) -> Type) -> (x : P (@B c c)) -> P (@B c f)) -> @Unit B c
%fix. (%self. %unroll \1 \0 \0) => (%self. %unroll \2 \1 \0) =>
((%self. %unroll \3 \2 \0) -> Type) -> \0 \2;
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%Unit I (unit : %self(unit). %unroll Unit unit u) =
%self(u). (P : (u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P (I u);
Unit @->
(I : I @-> (unit : unit @-> @Unit I unit) ->
(u : u @-> (P : (u : @Unit I unit) -> Type) -> (x : P @unit) -> P (@I unit u)) -> @Unit I unit) ->
(unit : unit @-> @Unit I unit) -> Type
Unit @->
(I : I @-> (unit : unit @-> @Unit I unit) ->
(u : u @-> (P : (u : @Unit I unit) -> Type) -> (x : P @unit) -> P (@I unit u)) -> @Unit I unit) ->
(unit : unit @-> @Unit I unit) -> Type
fix%Unit I (unit : %self(unit). %unroll Unit unit u) =
%self(u). (P : (u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P (I u);
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). %unroll Unit unit u.
fix%Unit (a : %self(b). %unroll Unit b b) (c : %self(d). %unroll Unit a d) =
(P : (e : %self(f). %unroll Unit a f) -> Type) -> P a -> P c;
Unit : Type
unit : Unit
Unit = %self(u)
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%False (f : %self(f). False f) =
fix%Unit (unit : %self(unit). Unit unit) =
%self(u). (P : (u : Unit unit) -> Type) -> P unit -> P u;
fix%Unit =
%self(u). (P : Unit -> Type) -> P (%fix(unit : Unit). P => x => x) -> P u;
%self(u). (P : Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
Unit1 = (unit : %self(unit). %self(u). %unroll Unit unit u) => %self(u). Unit unit u;
fix%Unit (a : %self(b). %unroll Unit b b) (c : %self(d). %unroll Unit a d) =
(P : (e : %self(f). %unroll Unit a f) -> Type) -> P a -> P c;
fix%Unit = %self(u). (P : Unit -> Type) -> P (%fix(unit). P => x => x) -> P u;
unit : %self(unit). (P : Unit -> Type) -> P unit -> P unit;
%coerce unit : %self(u). (P : Unit -> Type) -> P unit -> P u;
%fold unit : %self(u). (P : Unit -> Type) -> P unit -> P u;
() -> (P : Unit -> Type) -> P unit -> P u;
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
%fix(unit). %fix(u) : (I : ?) -> Unit (unit I) u.
P => (x : P (%unroll unit)) => (x : P u)
%fix(unit). %fix(u) : Unit unit u. P =>
(x : P (%fix(u) : Unit unit u. P => (x : P (%unroll unit)) => (x : P u))) =>
(x : P (%fix(u) : Unit unit u. P => (x : P (%unroll unit)) => (x : P u)))
%self(unit). %fix(). Unit (I unit) (I u)
%fix(unit) : %fix(u). Unit () u.
P => (x : P (%unroll unit)) => (x : P u)
M : %self(unit). %self(u). %unroll Unit unit u
%unroll M : %self(u). %unroll Unit unit u
fix%Unit (I : %self(I). ((A : Type) -> A -> A) -> Unit I) =
%self(u). (P : Unit I -> Type) ->
P (I (A => x => x)) -> P (I (A => %unroll u (_ => A)));
Unit1 = Unit (%fix(I). unit =>
%fix(u). (P : Unit I -> Type) => (
)
%self(u). (P : Unit I1 I2 -> Type) ->
P (I2 (%fix(unit). P => x => x)) -> P (I1 I2 u);
Unit1 = Unit (%fix(I1). I2 => x => x);
%fix(I1). unit =>
fix%unit (I : unit ==) : %self(u). %unroll Unit I unit u =
%unroll (%fix(u). (I : %unroll unit == u) -> Unit I unit u. P => x => I P x)
;
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x : A |- M : B
--------------------------------
%fix(x : A). M : %self(x : A). B
Γ |- M : %self(x). T
-----------------------------
%unroll M : T[x := %unroll M]
x == y /\ x <> y
Unit0 Unit unit u =
(P : Unit -> Type) -> P unit -> P u;
%self(Unit, _). (I : ?) -> Type
%self(F, f). (P : F -> Type) -> P f;
Unit0 U1 unit U2 u =
(P : (A : Type) -> A -> Type) -> P U1 unit -> P U2 u;
unit = %fix(U1, unit) : Unit0 U1 unit U1 unit = P => x => x;
Unit1 = %self(U, u). Unit0 _ unit U u;
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ |- M[x := %fix(x). M] : T
----------------------------
%fix(x) : T. M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
%self(False). (f : %self())
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit I1 = (
u = %fix(u) : (I2 : %unroll (unit I1) == (u I2)) -> Unit (unit I1) (u I2).
I2 => P => x => I P x;
)
%unroll (%fix(u) : (I : %unroll unit = %unroll u I) -> Unit unit (%unroll u I).
I => P => (x : P (%unroll unit)) => I P x)
(I : %unroll unit = %unroll (%fix(u) : (I : %unroll unit = %unroll u I) -> Unit unit (%unroll u I).
I => P => (x : P (%unroll unit)) => I P x) I) => P => (x : P (%unroll unit)) => I P x
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u) =
(P : (u : %self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
Unit =
%fix(Unit0). (unit : %self(unit). %unroll Unit0 unit (%fix(I). u => u)) =>
%fix(Unit1). (I : (u : %self(u). (P : (u : %unroll Unit1 I) -> Type) -> P unit -> P u) -> %unroll Unit1 I) =>
%self(u). (P : (u : %unroll Unit1 I) -> Type) -> P unit -> P u;
%self(False). (f : %self(f). False f) -> Type
%self(Unit). (u : (unit : ?) -> %self(u). Unit u) -> Type
fix%Unit
(I : %self(I).
(unit : %self(unit). Unit I unit) ->
(u : %self(u). (P : Unit I unit -> Type) -> P unit -> P (I unit u)) ->
%self(u). Unit I u
)
(unit : %self(unit). Unit I unit) =
%self(u). (P : Unit I unit -> Type) -> P unit -> P (I unit u);
fix%Unit
(A : %self(B).
(c : %self(d). Unit B d) ->
(e : %self(f). (P : Unit B c -> Type) -> P (%unroll c) -> P (B c f)) ->
%self(g). Unit B g
)
(h : %self(i). Unit A i) =
%self(j). (P : Unit A h -> Type) -> P (%unroll h) -> P (A h j);
Unit : Type
unit : Unit
Unit = %self(u). (P : Unit -> Type)
Unit0 W = %fix(Unit). (P : Unit -> Type) -> W Unit;
Unit1 = Unit0 (Unit => )
fix%Unit
(I : %self(I).
(unit : %self(unit). Unit I unit) ->
(u : %self(u). (P : Unit I unit -> Type) -> P unit -> P (I unit u)) ->
%self(u). Unit I u
)
(unit : %self(unit). Unit I unit) =
%self(u). (P : Unit I unit -> Type) -> P unit -> P (I (%unroll u));
fix%Unit (unit : %self(unit). Unit unit) =
%self(u). (P : Unit unit -> Type) -> P (%unroll unit) -> P u;
fix%unit : Unit unit =
%fix(u). P => x => x;
Unit = Unit (%fix(unit). %fix(u). P => x => x);
fix%Unit =
%self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
fix%Unit =
%self(u). (P : Unit unit -> Type) -> P (%unroll unit) -> P u;
inductionBool : forall (P : ((A : Type) -> A -> A -> A) -> Type), P false -> P true -> forall (b : (A : Type) -> A -> A -> A), P b
%fix(Unit). %self(b). (P : Unit -> Type) ->
P (%fix(unit). P => x => x) -> P b
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x == %fix(x). M |- M : T
----------------------------
%fix(x) : T. M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
type ty_term = TT_typed of { term : term; type_ : term }
and term =
| TT_var of { var : Var.t }
| TT_forall of { param : ty_pat; return : term }
| TT_lambda of { param : ty_pat; return : term }
| TT_apply of { lambda : term; arg : term }
| TT_self of { bound : pat; body : term }
| TT_fix of { bound : ty_pat; body : term }
| TT_unroll of { term : term }
and ty_pat = TP_typed of { pat : pat; type_ : term }
and pat = TP_var of { var : Var.t }
Makes GPT compress previous sessions, so that sessions can be merged.
I like succint and direct conversations, avoid apologizing.
Working on the core calculus for a dependently typed programming language.
Common pattern for types
Session Header:
- Date: 2023-03-14
- Session ID: 5d53713f-87d4-4fa8-8480-655bb0e5467d
- User: EduardoRFS
- Language: English
- Topic: Implementing Smol in OCaml
- Special Instructions: Be succint and direct, avoid apologizing
Session Context:
Smol is the core for a dependently typed programming language, based on the Calculus of Construction and extendended with self types similar to how Aaron Stump
and Peng Fu
describe at Self Types for Dependently Typed Lambda Encodings
.
The main changes from the Calculus of Construction are the following rules
-----------
Type : Type
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x == %fix(x). M |- M : T
----------------------------
%fix(x) : T. M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
The context was extended with definition equalities such that inside of the fixpoint, x
is known to be equal to the fixpoint.
On the implementation, the current tree is defined as
type ty_term = TT_typed of { term : term; type_ : term }
and term =
| TT_var of { var : Var.t }
| TT_forall of { param : ty_pat; return : term }
| TT_lambda of { param : ty_pat; return : term }
| TT_apply of { lambda : term; arg : term }
| TT_self of { bound : pat; body : term }
| TT_fix of { bound : ty_pat; body : term }
| TT_unroll of { term : term }
and ty_pat = TP_typed of { pat : pat; type_ : term }
and pat = TP_var of { var : Var.t }
module Context : sig
type t
type term
val empty : t
val extend_abstract : t -> Var.t -> term -> t
val extend_alias : t -> Var.t -> term -> t
val lookup : t -> Var.t -> term option
end
Assume
module Ttree : sig
type ty_term = TT_typed of { term : term; type_ : term }
and term =
| TT_var of { var : Var.t }
| TT_forall of { param : ty_pat; return : term }
| TT_lambda of { param : ty_pat; return : term }
| TT_apply of { lambda : term; arg : term }
| TT_self of { bound : pat; body : term }
| TT_fix of { bound : ty_pat; body : term }
| TT_unroll of { term : term }
and ty_pat = TP_typed of { pat : pat; type_ : term }
and pat = TP_var of { var : Var.t }
end
module Subst : sig
val subst_term : from:Var.t -> to_:Var.t -> Ttree.term -> Ttree.term
end
module Context : sig
type context
type t = context
val initial : context
val enter : Var.t -> Ttree.term -> context -> context
val lookup : Var.t -> context -> Ttree.term option
end
Then implement
module Equal : sig
val equal_term : Context.t -> received:Ttree.term -> expected:Ttree.term -> unit
end
%fix(False) : Type. %self(f). (P : %unroll False -> Type) -> P f
%fix(False) : Type. %self(f). (P : %unroll False -> Type) -> P f
%unroll (%fix(False\1) : Type. %self(f). (P : %unroll False -> Type) -> P f)
%self(f). (P : %unroll False -> Type) -> P f
%unroll (%fix(False\1) : Type. %self(f). (P : %unroll False -> Type) -> P f)
expected : %self(f). (P : %unroll False\0 -> Type) -> P f
received : f\1
expected : %self(f : %unroll False). (P : %unroll False -> Type) -> P f
received : %self(f : %unroll False). (P : %unroll False -> Type) -> P f
%fix(False\1) : Type. %self(f). (P : %unroll False -> Type) -> P f
expected : %unroll (%fix(False\1) : Type. %self(f). (P : %unroll False -> Type) -> P f)
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %unroll (%fix(False) : Type. %self(f) : %unroll False/2. (P : %unroll False/1 -> Type) -> P f)
received : %self(f) : %unroll False/2. (P : %unroll False/1 -> Type) -> P f
expected : %self(f) : %unroll False/2. (P : %unroll False/1 -> Type) -> P f
received : %self(f) : %unroll False/2. (P : %unroll False/1 -> Type) -> P f
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : (u : %self(f). Unit unit u) -> Type) -> P unit -> P u;
%fix(unit) : %self(u). Unit unit u.
%fix(u) : Unit unit !u. (P : (u : %self(f). Unit unit u) -> Type) => (x : P (%unroll !unit)) => x
expected : P (%fix(u) : Unit unit !u. (P : (u : %self(f). Unit unit u) -> Type) => (x : P (%unroll !unit)) => x)
received : P (%fix(u) : Unit unit !u. (P : (u : %self(f). Unit unit u) -> Type) => (x : P (%unroll !unit)) => x)
expected : P u\0
received : P (%fix(u\0) : Unit unit u. (P : (u : %self(f). Unit unit u) -> Type) => (x : P (%unroll unit)) => x)
expected : %unroll False
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %unroll False2
received : %self(f). (P : %unroll False1 -> Type) -> P f
expected : %unroll (%fix(False1). %self(f). (P : %unroll False1 -> Type) -> P f)
received : %self(f). (P : %unroll False1 -> Type) -> P f
expected : %self(f). (P : %unroll False1 -> Type) -> P f
received : %self(f). (P : %unroll False1 -> Type) -> P f
expected : %self(f). (P : %unroll (%frozen(False3). %self(f). (P : %unroll False3 -> Type) -> P f) -> Type) -> P f
received : %self(f). (P : %unroll (%frozen(False2). %self(f). (P : %unroll False2 -> Type) -> P f) -> Type) -> P f
P : %unroll (%expanded(False). %self(f). (P : %unroll False -> Type) -> P f) -> Type
expected : %unroll (%expanded(False). %self(f). (P : %unroll False -> Type) -> P f)
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %self(f). (P : %unroll False -> Type) -> P f
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %self(f). (P : %unroll (%expand (%frozen False)) -> Type) -> P f
received : %self(f). (P : %unroll (%expand False) -> Type) -> P f
expected : %unroll (%expanded(False). %self(f). (P : %unroll False -> Type) -> P f)
received : %self(f). (P : %unroll (%expanded(False). %self(f). (P : %unroll False -> Type) -> P f) -> Type) -> P f
expected : %self(f). (P : %unroll (%frozen(False). %self(f). (P : %unroll False -> Type) -> P f) -> Type) -> P f
received : %self(f). (P : %unroll (%expanded(False). %self(f). (P : %unroll False -> Type) -> P f) -> Type) -> P f
expected : %unroll (%frozen(False). %self(f). (P : %unroll () -> Type) -> P f)
received : %self(f). (P : %unroll (%frozen(False). %self(f). (P : %unroll () -> Type) -> P f) -> Type) -> P f
expected : %unroll False
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %unroll (%fix(False). %self(f). (P : %unroll False -> Type) -> P f)
received : %self(f). (P : %unroll (%fix(False). %self(f). (P : %unroll False -> Type) -> P f) -> Type) -> P f
expected : %unroll (%fix(False). %self(f). (P : %unroll False -> Type) -> P f)
received : %self(f). (P : %unroll False -> Type) -> P f
expected : %self(f). (P : %unroll False -> Type) -> P f
received : %self(f). (P : %unroll False -> Type) -> P f
%fix(Unit). %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
expected : %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
%fix(Unit). %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
%fix(unit) : %unroll Unit. P => x => x
expected : P (%fix(unit). P => x => x)
received : P (%fix(unit). P => x => x)
%frozen(Unit). %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
expected : %unroll Unit
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
expected : %unroll (%fix(Unit). %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u)
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
expected : %self(u). (P : %unroll (%frozen(Unit). %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u) -> Type) -> P (%fix(unit). P => x => x) -> P u
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
T = %self(u). (P : Unit unit -> Type) -> P (%unroll unit) -> P u;
fix%unit
Unit0 (unit : %self(unit). Unit unit) =
(P : (u : %self(u). Unit0 u) -> Type) -> P unit -> P unit;
fix%unit : Unit0 unit = P => x => x;
%self(unit). %self(u). Unit unit u
%self(u). Unit unit u
fix%Unit (unit : %self(unit). %self(u). Unit unit u) u =
(P : (u : %self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). Unit unit u =
fix%Unit =
%self(u).
(P : (u : %self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
(P : Unit -> Type) -> P unit -> P u;
Ord = (Base : Type) -> (Wrap : Type -> Type) -> Type;
Zero : Ord = Base => Wrap => Base;
Succ (N : Ord) : Ord = Base => Wrap => Wrap (N Ord Base);
False0 = (A : Type) -> A;
FalseN (N : Ord) : Ord =
N ((False : Type) -> (f : False) -> Type) False0
(False => (f : False) => (P : False -> Type) -> P f);
False0 : (f0 : False) -> Type = f0 => (P : False -> Type) -> P f0;
False1 : (f0 : False) -> (f1 : False0 f0) -> Type = f0 => f1 => (P : False0 f0 -> Type) -> P f1;
False2 : (f0 : False) -> (f1 : False0 f0) -> (f2 : False1 f0 f1) -> Type
= f0 => f1 => f2 => (P : False1 f0 f1 -> Type) -> P f2;
FalseT (N : Ord) = N Falsep
f0 => f1 => f (P : ((P : False0 -> Type) -> P f0) -> Type) -> P f1;
f (f (f False0))
f (f (f n))
x = (f : False 2 )
// TODO: generic base case for all types
Unit0 = (A : Type) -> (x : A) -> A;
unit0 : Unit0 = A => x => x;
Unit (N : Ord) = N Unit0 (Unit => => (P : ))
(A : Type) => (x : A) => x;
False False (f : False) = (P : False -> Type) -> P f;
(f : Self False)
%fix(False) : Type. %self(f : %unroll False).
(P : %unroll False -> Type) -> P f;
%self(A, False : (f : A) -> Type).
(f : %self(T, f : A). False f) -> Type;
%fix(Unit) : Type. %self(u : %unroll Unit).
(P : %unroll Unit -> Type) ->
P (%fix(unit). (P : %unroll Unit -> Type) => (x : P unit) => x) -> P u
%fix(Unit). %self(u). (P : Unit -> Type) -> P (%fix(unit). P => x => x) -> P u
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
ind_unit : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u;
(x : A) -> B : Type
%unroll u : (P : Unit -> Type) -> P unit -> P u
fix%Unit = (
unit = %fix(unit : %unroll Unit). (P : %unroll Unit -> Type) => (x : P unit) => x;
%self(u : %unroll Unit). (P : %unroll Unit -> Type) -> P unit -> P u
);
[%fix(unit). (P : Unit -> Type) => (x : P unit) => x : Unit,
%self(u : Unit). (P : Unit -> Type) -> P unit -> P u === Unit]
%self(False : T). (f : %self(f). %unroll False f) -> Type
%fix(FalseT) : Type. %self(False : FalseT).
(f : %fix(fT) : Type. %self(f : fT). (False : (f : fT) -> Type) f) -> Type
%fix(TFalse) : Type. %self(False : %unroll TFalse).
(f : %fix(Tf) : Type.
%self(f : %unroll Tf). %unroll (False : %self(False). (f : %unroll Tf) -> Type) f) -> Type
%fix(TFalse) : Type. %self(False : %unroll TFalse).
(f : %fix(Tf) : Type.
%self(f : %unroll Tf). %unroll (False : %self(False). (f : %unroll Tf) -> Type) f) -> Type
%fix(TFalse) : Type. %self(False : %unroll TFalse).
(f : %fix(Tf) : Type, False : %self(False). (f : %unroll Tf) -> Type.
%self(f : %unroll Tf). %unroll False f) -> Type
%self(False). (f : %self(f : %unroll Tf). %unroll False f) -> Type
%self(f : %unroll Tf). %unroll (False : %self(False). (f : %unroll Tf) -> Type) f === %unroll Tf
False : FalseT
FalseT === (f : fT) -> Type
%fix(unit). (P : Unit -> Type) => (x : P unit) => x
%self(u : Unit). (P : Unit -> Type) -> P unit -> P u
%fix(FalseT) : Type. %self(False : FalseT).
(f : %fix(fT) : Type. %self(f : fT). (False : (f : fT) -> Type) f) -> Type
%fix(TFalse) : Type. %self(False : %unroll TFalse).
(f : %fix(Tf) : Type, False : %self(False). (f : %unroll Tf) -> Type.
%self(f : %unroll Tf). %unroll False f) -> Type
%fix(False).
%self(f). (P : %unroll False -> Type) -> P f
fix%Unit (unit : %self(unit). %self(u). Unit unit u) u =
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). Unit unit u = P => x => (x : P u)
fix%Unit = (
unit : %unroll (Unit 1) = %fix(u). P => x => x;
%self(u). (P : %unroll (Unit 0) -> Type) -> P unit -> P (u : Unit 1)
);
%fix(Unit). (P : Unit -> Thype)
double = (x) => x + x;
double(2);
((x) => x + x)(2)
(x + x)[x := 2]
2 + 2
4
double(potato);
((x) => x + x)(potato);
(x + x)[x := potato]
potato + potato
double(2);
((x) => x + x)(2)
(x + x)[x := 2]
x[x := 2] + x[x := 2]
2 + 2
4
double(potato) === potato + potato
name(user) = user.name;
name({ name : "Eduardo" });
{ name : "Eduardo" }.name
"Eduardo"
double = (x) => x + x;
name = (user) => user.firstName + " " + user.lastName;
r0 : Register;
r1 : Register;
r2 : Register;
r3 : Register;
one = imm(r0, 1);
two = imm(r1, 1);
(three, one) = add(two, one);
(three, three) = mov(three, one);
Teika is a dependently typed programming language with inductive types, the main syntax can be seen as described by the following rules:
Type
is the type of all types, theType
ofType
is Type(x : A) => m
is a function that accepts x of type A and return M of type B(x : A) -> B
is a function type that accepts x of type A returns a type Bx = m; n
is a let that expresses that in n x will be equal to m
Induction of the booleans is defined in the context as following
Bool : Type;
true : Bool;
false : Bool;
ind_bool : (b : Bool) -> (P : Bool -> Type) -> (t : P true) -> (f : P false) -> P b;
%fix(False). %self(f). (P : %unroll (%unfold False) -> Type) -> P f;
%fix(Unit). (
unit : %unroll Unit = %fix(u). P => (x : P (%unfold u)) => (%fold x);
%self(u). (P : %unroll (%unfold Unit)) -> P unit -> P u;
);
P (%fix(u). P => (x : P (%unfold u)) => (x : P u))
P u
%fix(Unit). (
unit : %unroll Unit = %fix(u). P => (x : P u) => x;
%self(u). (P : %unroll Unit -> Type) -> P unit -> P u;
);
expected : %unroll Unit
%fix(Unit). (
unit : %unroll Unit = %fix(u). (P : %unroll Unit -> Type) => (x : P u) => x;
%self(u). (P : %unroll Unit -> Type) -> P unit -> P u;
);
(P : %unroll Unit -> Type) -> P (%fix(u : %unroll Unit). (P : %unroll Unit -> Type) => (x : P u) => x) -> P (%fix(u : %unroll Unit). (P : %unroll Unit -> Type) => (x : P u) => x)
(P : %unroll Unit -> Type) -> P (%fix(u : %unroll Unit). (P : %unroll Unit -> Type) => (x : P u) => x) -> P (%fix(u : %unroll Unit). (P : %unroll Unit -> Type) => (x : P u) => x)
False = %fix(False). (f : %self(f). %unroll False f) =>
(P : (%self(f). %unroll False f -> Type)) -> P f;
False = %self(f). (P : (%self(f). %unroll False f -> Type)) -> P f;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) u =
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). : Unit unit u =
%fix(u). P => (x : P (%unroll unit)) => (x : P u);
%fix(u). P => (x : P (%unroll unit)) => x
%fix(u). P => (x : P (%unroll unit)) => (x : P (%fix(u). P => (x : P (%unroll unit)) => x))
expected : P (%fix(u). P => (x : P (%unroll unit)) => x)
received : P u
%unroll (%fix(T) : Type. T)
%unroll (%fix(T) : Type. %unroll T)
%unroll (%frozen(T) : Type. %unroll T)
%fix(Unit).
%fix(Bool). (
macro%true false = %fix(true : %unroll Bool). P => (t : P true) => (f : P false) => t;
macro%false true = %fix(false : %unroll Bool). P => (t : P true) => (f : P false) => f;
true = macro%true (macro%false true);
false = macro%false (macro%true false);
%self(b). (P : %unroll Bool -> Type) -> P true -> P false -> P b;
);
fix%Bool
(true : %self(true). (false : %self(false). %self(b). Bool (%unroll true false) false b) -> %self(b). Bool (%unroll true false) false b)
(false : %self(false). %self(b). Bool (%unroll true false) false b) (b : %self(b). Bool (%unroll true false) false b) =
(P : (%self(b). Bool (%unroll true false) false b) -> Type) -> P (%unroll true false) -> P (%unroll false) -> P b;
fix%true (false : %self(false). %self(b). Bool (%unroll true false) false b) : %self(b). Bool (%unroll true false) false b
= %fix(b). P => t => f => (t : P b);
fix%false : %self(b). Bool (%unroll true false) false b
= %fix(b). P => t => f => (t : P b);
%fix(Bool). (
true : %unroll Bool = %fix(true). P => (t : P true) => (f : P (%fix(false). P => (t : P true) => (f : P false) => f)) => t;
false : %unroll Bool = %fix(false). P => (t : P (%fix(true). P => (t : P true) => (f : P false) => t)) => (f : P false) => f;
%self(b). (P : %unroll Bool -> Type) -> P true -> P false -> P b;
);
expected : %self(b). (P : %unroll Bool -> Type) -> P true -> P false -> P b
received : %self(true). (P : %unroll Bool -> Type) => (t : P true) => (f : P (%fix(false). P => (t : P true) => (f : P false) => f)) => t
P (%unroll unit)
P (%unroll (%unfold unit))
P u
Unit = %self(u). Unit unit u;
unit (_ => Unit) unit == unit
(u : Unit) => u (u => u (_ => Unit) unit == unit);
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u
expected : P (%fix(u). P => (x : P (%unroll unit)) => (x : P u))
received : P (%fix(u). P => (x : P (%unroll unit)) => (x : P u))
expected : %fix(u). P => (x : P (%unroll unit)) => (x : P u)
received : %fix(u). P => (x : P (%unroll unit)) => (x : P u)
(P => (x : P (%unroll (%unfold unit))) => x))
f = (u Ç )
expected : P (%fix(u). P => (x : P (%unfold u)) => x)
received : P (%fix(u). P => (x : P (%unfold u)) => x)
expected : %self(f). (P : %unroll False -> Type) -> P (f : %unroll False)
received : %self(f). (P : %unroll False -> Type) -> P (f : %unroll False)
expected : %unroll (%unfold False)
received : %unroll False
Γ, False == %fix(False). _A, f : %self(f). _B
(P : %unroll False -> Type) -> P f;
expected : _A[False := %fix(False). _A]
received : %self(f). _B
False = %fix(False 1).
%self(f). (P : %unroll (False 0) -> Type) -> P (f : %unroll (False 1));
%self(f). (P : %unroll (False 0) -> Type) -> P (f : %unroll (False 0))
%self(f). (P : %unroll (False 0) -> Type) -> P (f : %unroll (False 1))
Unit = %fix(Unit 1). (
unit : %unroll (Unit 1) = %fix(u). P => x => x;
%self(u). (P : %unroll (Unit 0) -> Type) -> P unit -> P (u : Unit 1)
);
%unroll (%fix(Unit 0). (
unit : %unroll (Unit 1) = %fix(u). P => x => x;
%self(u). (P : %unroll (Unit 0) -> Type) -> P unit -> P (u : Unit 1)
))
1 + 2 = 3
2 - y = y
y + 2 - y = y + y
2 = 2y
2 / 2 = 2y / 2
1 = y
1 + 2 // 3
f = x => 1 + x;
f(2)
(x => 1 + x)(2)
(1 + x)[x := 2]
1 + 2
f(3)
(x => 1 + x)(3)
(1 + x)[x := 3]
1 + 3
0 + n = n
n + 1 = n
0
S(n) = n + 1
S(0) = 1
S(S(0)) = 2
zero = z => s => z;
succ = n => z => s => s(n(z)(s));
one = succ(zero);
two = succ(one);
add = n => m => n(m)(succ);
succ(succ(two));
one = z => s => s(z);
two = z => s => s(s(z));
three = z => s => s(s(s(z)));
P(n)
0
S(n)
Array.get : Array<A> -> Nat -> A;
arr => (Array.get(arr, 0), Array.get(arr, 1));
Array.get : Array<A> -> Nat -> (Array<A>, A);
arr => (
(arr, x) = Array.get(arr, 0);
(arr, y) = Array.get(arr, 1);
(x, y)
);
x => x
x => x + x
Unit : Type;
unit : Unit;
ind : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u;
// internalizing induction
((n : Nat) -> P n -> P (succ n))
Nat = (A : Type) -> A -> (Nat -> A) -> A
Unit = (P : Unit -> Type) -> P unit -> P u;
%fix(Unit). %self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
// no self assumption for self
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, A : Type, x : A |- M : T
------------------------------
%fix(A, x). M : %self(A, x). T
Γ |- M : %self(A, x). T
-------------------------------------------
%unroll M : T[A := %self(A, x). T | x := M]
%self(False, f). (P : False -> Type) -> P f;
%fix(Unit, unit). (P : Unit -> Type) => (x : P unit) => x;
%self(Unit, unit). (P : Unit -> Type) -> P unit -> P unit
%self(Unit, u). (P : Unit -> Type) -> P unit -> P u;
Unit = %self(Unit, u). (P : Unit -> Type) -> P unit -> P u;
%self(U, unit). Unit unit;
%fix(U, u : ) :
(A : Type) => (x : A) =>
(eq : (P : (A : Type) -> A -> Type) -> P Type A -> P Type Nat) =>
eq (A => x => )
%fix(Unit). %self(u : %unroll (%unfold Unit)). (
unit = %fix(u : %unroll (%unfold Unit)). (P : %unroll (%unfold Unit) -> Type) => (x : P (%unfold u)) => x;
(P : %unroll (%unfold Unit) -> Type) -> P unit -> P (%unfold u)
);
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : (u : %self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit = %fix(unit). %fix(u) : Unit unit u.
(P : (u : %self(u). Unit unit u) -> Type) => (x : P (%unroll unit)) => (x : P u);
Unit = %self(u). Unit unit u;
fix%Unit = %self(u). (P : Unit -> Type) -> P (%fix(u : Unit). (P : Unit -> Type) -> P u -> P u) -> P u
expected : (P : Unit -> Type) -> P (%fix(u : Unit). (P : Unit -> Type) -> P u -> P u) -> P (%fix(u : Unit). (P : Unit -> Type) -> P u -> P u)
received : (P : Unit -> Type) -> P (%fix(u : Unit). (P : Unit -> Type) -> P u -> P u) -> P (%fix(u : Unit). (P : Unit -> Type) -> P u -> P u);
expected : P (%fix(u) : Unit unit u. (P : (u : %self(u). Unit unit u) -> Type) => (x : P (%unroll unit)) => (x : P u))
received : P (%fix(u) : Unit unit u. (P : (u : %self(u). Unit unit u) -> Type) => (x : P (%unroll unit)) => (x : P u))
pred => case (%unfold pred)
(P : %unroll (%unfold Unit) -> Type) -> P unit -> P (%unfold u)
(P : %unroll (%unfold Unit) -> Type) -> P (%unfold u) -> P (%unfold u)
fix%False = %self(f). (P : %unfold False -> Type) -> P f;
expected : %unfold False;
received : %self(f). (P : %unfold False -> Type) -> P f;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : Unit -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). Unit (%unfold unit) u = %fix(u) : Unit (%unfold unit) u.
(P : Unit -> Type) => (x : P (%unroll (%unfold unit))) => x;
fix%unit : %self(u). Unit (%unfold unit) u =
%fix(u) : Unit (%unfold unit) u. P => x => x;
(P : Unit -> Type) -> P (%unroll (%unfold unit)) -> P (%unroll (%unfold unit));
(P : Unit -> Type) -> P (%unroll (%unfold unit)) -> P
fix%Unit = %self(u). (P : %unfold Unit -> Type) ->
P (%fix(unit). P => x => x) -> P u;
fix%Unit = %self(u). (P : %unfold Unit -> Type) ->
P (%fix(unit). P => (x : P unit) => x) -> P u;
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x == %fix(x). M |- M : T
---------------------------
%fix(x). M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
fix%Unit = %self(u). (P : %unfold Unit -> Type) ->
P u -> P (%fix(u). P => (x : P u) => (x : P (%fix(u). P => (x : P u) => x)));
symm eq = eq (x => x);
fix%Unit = %self(u). (P : Unit -> Type) ->
P (%fix(u). P => (x : P u) => x)
u == unit
expected : P (%fix(u). P => (x : P u) => x)
received : P (%fix(u). P => (x : P u) => x)
(P : %unfold Unit -> Type) -> P unit -> P u
(P : %unfold Unit -> Type) -> P (%fix(unit). P => (x : P unit) => x) -> P u
%fix(unit). (P : %unfold Unit -> Type) => (x : P unit) => (x : P unit)
%fix(unit). (P : %unfold Unit -> Type) => (x : P unit) => (x : P unit)
%self(unit). (P : %unfold Unit -> Type) -> P unit -> P unit
M : %self(x). T
received : P unit
expected :
received : P (%fix(unit). P => x => x)
expected : P (%fix(unit). P => x => x)
fix%Unit =
%self(u). (P : !Unit -> Type) -> P u^ -> P (%fix(u). P => (x : P u^) => !x);
expected : (P : Unit -> Type) -> P u^ -> P (%fix(u). P => (x : P u^) => !x)
received : (P : Unit -> Type) -> P u^ -> P (%fix(u). P => (x : P u^) => !x)
fix%Unit =
%self(u). (P : !Unit -> Type) -> P (%fix(u). P => (x : P u) => [x]) -> P u^;
expected : (P : !Unit -> Type) -> P (%fix(u). P => (x : P u) => [x]) -> P u^
received : (P : !Unit -> Type) -> P u -> P u
fix%Unit = %self(u).
(P : Unit -> Type) -> P [u] -> P (%fix(u). P => (x : P [u]) => x);
expected : (P : (!Unit)^ -> Type) -> P [u] ->
received : (P : (!Unit)^ -> Type) -> P [u] -> P [u]
fix%Unit = %self(u).
(P : %unroll Unit -> Type) -> P (%fix(u). P => (x : P u) => x) -> P u;
(u : Unit) => %unroll u ()
%unroll Unit
(P : %unroll Unit -> Type) -> P (%fix(u). P => (x : P u) => x) -> P u
%unroll Unit
P (%fix(u). P => (x : P u) => x) -> P (%fix(u). P => (x : P u) => x)
P (%fix(u). P => (x : P u) => x) -> P (%fix(u). P => (x : P u) => x)
fix%False = %self(f). (P : %unroll (%unfold False) -> Type) -> P f;
%unroll (%fix(False). %self(f). (P : %unroll (%unfold False) -> Type) -> P f)
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u)
= (P : (u : %self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). Unit unit u = %fix(u) : Unit unit u.
P => (x : P u) => x;
expected : P u -> P u
received : P (%unroll (%unfold unit)) -> P u
%fix(T) : Type. %unroll !T
%fix(Nat). (A : Type) -> A -> (%unroll Nat -> A) -> A;
%fix(Nat). (A : Type) -> A -> (%unroll (%fix(Nat). (A : Type) -> A -> (Nat -> A) -> A) -> A) -> A
%fix(Nat). (A : Type) -> A -> (%unroll !Nat -> A) -> A;
%fix(Nat). (A : Type) -> A -> (!Nat -> A) -> A;
| (tag : true, A)
| (tag : false, B)
type Return<A> =
| { tag: "tail"; thunk: () => Return<A> }
| { tag: "value"; return: A };
const $call = (x) => {
while ($continue !== null) {
x = $handler();
}
return x;
};
function* () {
yield f(x);
}
f(x);
// TODO: benchmark against dumb function
// TODO: benchmark techniques such as full CPS to test engine inliners
$tail = true;
$continue = () => {};
const $apply = (x) => {
while ($tail) {
$tail = false;
x = $continue();
}
return x;
};
$apply(f)(x);
let f = fun [@async] x -> 1
function kid(x, k) {
return k(x);
}
function kid(x, k) {
return $next(k, x);
}
let kid x k = k x
let rec rev acc l =
match l with
| [] -> acc
| el :: tl -> rev (el :: acc) tl
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u)
(u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u : %self(u). %unroll Unit (%fix(unit). u) u
= %fix(u). P => (x : P (%fix(unit). u)) => x;
expected : %self(u). (P : (%self(u). %unroll Unit (%fix(unit). u) u) -> Type) -> P (%unroll (%fix(unit). u)) -> P u
received : %self(u). (P : (%self(u). %unroll Unit (%fix(unit). u) u) -> Type) -> P (%unroll (%fix(unit). u)) -> P (%unroll (%fix(unit). u))
expected : P u -> P u
received : P u -> P u
expected : P u -> P u
received : P u -> P u
(P : )
(P : (%self(u). Unit unit u) -> Type) -> P unit -> P u
Unit (%fix(unit). u) u
u : %self(u). Unit (%fix(unit). u) u =
%fix(u). (P : (%self(u). Unit (%fix(unit). u) u) -> Type) => (x : P (%fix(unit). u)) => x;
unit2 : %self(unit). %self(u). Unit unit u = %fix(unit3). u;
expected : %self(u). Unit (%fix(unit3). u) u
received : %self(u). Unit (%fix(unit). u) u
expected : (P : (%self(u). Unit (%fix(unit). u) u) -> Type) -> P (%fix(unit). u) -> P (%fix(unit). u)
received : (P : (%self(u). Unit (%fix(unit). u) u) -> Type) -> P (%fix(unit). u) => P (%fix(unit). u)
expected : %self(u). Unit (%fix(unit). u) u
received : %self(u). Unit (%fix(unit). u) u;
fixunit (u : %self(u). Unit (unit u) u) = u;
x = %fix(u) : Unit (unit u) u. P => (x : P (unit u)) => x;
(P : (%self(u). Unit (unit b) u) -> Type) -> P b -> P b
(P : (%self(u). Unit (unit b) u) -> Type) -> P b -> P b
unit : %self(unit). %self(u). Unit unit u;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : (%self(u). Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit = %fix(u) : Unit unit u. P => (x : P (%unroll unit)) => x;
fix%Unit (unit : %self(unit). %self(u). Unit unit u) (u : %self(u). Unit unit u) =
(P : Unit unit u -> Type) -> P (%unroll (%unroll unit)) -> P (%unroll u);
fix%unit = %fix(u) : Unit unit u. P => (x : P (%unroll unit)) => x;
%fix(u). P => (x : P (%frozen unit)) => x
%self(u). (P : (%self(u). Unit unit u) -> Type) -> P (%fix(u). P => (x : P (%frozen unit)) => x) -> P (%fix(u). P => (x : P (%frozen unit)) => x)
%self(u). (P : (%self(u). Unit unit u) -> Type) -> P (%fix(u). P => (x : P (%frozen unit)) => x) -> P (%fix(u). P => (x : P (%frozen unit)) => x)
fix%Unit : Type = (
fix%unit : Unit = (P : Unit -> Type) => (x : P unit) => x;
%self(u). (P : Unit -> Type) -> (x : P unit) -> P u;
);
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x
fix%False (f : %self(f). False f) =
(P : (%self(f). False f) -> Type) -> P f;
False = %self(f). False f;
Unit : %self(Unit). (u : %self(u). Unit u) -> Type;
unit : %self(u). Unit u;
Unit = u => (P : (%self(u). Unit u) -> Type) -> P unit -> P u;
unit = (P : (%self(u). Unit u) -> Type) => (x : P unit) => x;
%fix(u). P => x => x
%self(u). (P : (%self(u). Unit u) -> Type) -> P (%fix(u). P => x => x) -> P (%fix(u). P => x => x)
%self(unit). (P : (%self(u). Unit u) -> Type) -> P (%fix(u). P => x => x) -> P (%fix(u). P => x => x)
%fix(M : {
Unit : %self(Unit). (u : %self(u). Unit u) -> Type;
unit : %self(u). Unit u;
}). {
Unit = (u : %self(u). M.Unit u) => (P : (%self(u). M.Unit u) -> Type) -> P M.unit -> P u;
unit = (P : (%self(u). M.Unit u) -> Type) => (x : P M.unit) => x;
};
%fix(M : {
Unit : Type;
unit : Unit;
}). {
Unit = %self(u).(P : (%self(u). M.Unit u) -> Type) -> P M.unit -> P u;
unit = (P : (%self(u). M.Unit u) -> Type) => (x : P M.unit) => x;
};
fix%Unit = %self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
%self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u
u : %self(u). _A
Unit : Type
%self(u) : Unit. P => (x : P u) => x
%fix(u) : Unit. P => (x : P u) => x
%self(u). {A} {B}. A -> B -> B
expected : (P : (%self(u). Unit u) -> Type) -> P (%fix(u). P => x => x) -> P (%fix(u). P => x => x)
received : (P : (%self(u). Unit u) -> Type) -> P (%fix(u). P => x => x) -> P (%fix(u). P => x => x)
%self(unit). (P : (%self(u). Unit u) -> Type) -> P unit3 -> P unit
%self(unit2). (P : (%self(u). Unit u) -> Type) -> P unit2 -> P unit2
%fix(Unit : Type; unit : Unit). (
%self(u). (P : Unit -> Type) -> P unit -> P u;
);
expected :
%self(a). (P : Unit -> Type) -> (x : P (%fix(c). P => (x : P c) => x)) -> P a
%self(b). (P : Unit -> Type) -> (x : P b) -> P b
(P : Unit -> Type) -> (x : P (%fix(c). P => (x : P c) => x)) -> P d
(P : Unit -> Type) -> (x : P d) -> P d
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
T = %self(u). %unroll Unit (%fix(unit). u) u;
T = %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
u : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
fix%unit : %self(u). %unroll Unit unit u =
%fix(u) : %unroll Unit (%fix(unit). u) u. P => x => x;
expected : %self(u). %unroll Unit unit u
received : %self(u). %unroll Unit (%fix(unit). u) u
expected : %self(unit). %self(u). %unroll Unit unit u
received : %self(unit). %self(u). %unroll Unit (%fix(unit). u) u
expected : %self(unit). %self(u). (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u
received : %self(unit). %self(u).
expected : %self(u). %unroll Unit (%fix(unit). u) u
received : (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u
%self(t). P (%unroll (%fix(x). t)) -> P t
%self(t). P (%unroll (%fix(x). t)) -> P (%unroll (%fix(x). t))
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u : %self(u). %unroll Unit (%fix(unit). %fix(u). P => x => x) u
%unroll Unit (%fix(unit). %fix(u). P => x => x) u
%fix(unit). %fix(u) : %unroll Unit unit u. P => x => x
expected : P (%unroll unit) -> P (%fix(u). P => x => x)
received :
expected : %self(unit). %self(u). %unroll Unit unit u
received :
u : %self(u). %unroll Unit (%fix(unit). %fix(u). P => x => x) u
= %fix(u). P => x => x;
unit : %self(unit). %self(k). %unroll Unit unit k = %fix(unit). u;
expected : %unroll Unit (%fix(unit). %fix(u). P => x => x) u
received : %unroll Unit (%fix(unit). %fix(u). P => x => x) u
expected : %unroll Unit (%fix(unit). %fix(u). P => x => x) u
received :
fix%unit : %self(u). %unroll Unit unit u =
%fix(u) : %unroll Unit (%fix(unit). u) u. P => x => x;
expected : %self(u). %unroll Unit (%fix(unit). ) u
received : %self(u). %unroll Unit (%fix(unit). u) u
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
expected : %self(u). %unroll Unit unit u
received : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
%self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
%fix(T). %self(u). %unroll Unit (%fix(unit) : %unroll T. u) u
u : %self(u). %unroll Unit (%fix(unit). u) u
= %fix(u). P => x => x;
unit
: %self(unit). %self(u). %unroll Unit unit u
= %fix(unit). u;
expected : %self(u). %unroll Unit (%fix(unit). u) u
received : %self(u). %unroll Unit (%fix(unit). u) u
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u : %self(u). %unroll Unit (%fix(unit). u) u
= %fix(u). P => x => x;
unit
: %self(unit). %self(u). %unroll Unit unit u
= %fix(unit). u
u : %self(u). _A
unit : %self(unit). _B
_B : %self(u). _A
%self(unit). %self(u). _A : %self(unit). %self(u). %unroll Unit unit u
u : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
expected : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
received : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
= %fix(u). P => x => x;
unit = %fix(unit) : %self(u). %unroll Unit unit u. u;
Unit2 = %self(u). Unit unit u;
expected : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
received : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
unit = %fix(unit) : %self(u). %unroll Unit unit u.
%fix(u). (P : (%self(u). %unroll Unit unit u) -> Type) => (x : P (%unroll unit)) => x
expected : %self(u). (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u
received : %self(k). (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll unit);
%self(u). %unroll Unit (%fix(unit). %fix(u). P => x => x) u;
%unroll Unit ? u
u = %fix(u) : %unroll Unit ? u. P => x => x;
unit =
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
u = %fix(u) : %unroll Unit (%fix(unit). u) (%fix(u). P => x => x). P => x => x;
%self(unit). %self(u). %unroll Unit unit (%fix(u) : %unroll Unit unit u. P => x => x)
expecected : %unroll Unit unit (%fix(u) : %unroll Unit unit u. P => x => x)
received : %unroll Unit unit unit
%self(u). %unroll Unit
(%fix(unit) : %self(u). %unroll Unit unit (%fix(u). P => x => x). u)
(%fix(u). P => x => x)
expected : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
received : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) (%fix(u). P => x => x)
expected : %unroll Unit (%fix(unit). %fix(u). P => x => x) (%fix(u). P => x => x)
received : %unroll Unit (%fix(unit). %fix(u). P => x => x) (%fix(u). P => x => x)
expected : P u -> P (%fix(u). P => x => x)
received : P u -> P u
unit = %fix(unit) : %self(u). %unroll Unit unit u.
%fix(u). P => x => x;
expected : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. %fix(u) : %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u. P => x => x) u
received : %self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u. u) u
Unit2 = %self(u). Unit unit u;
Term =
| Type
| x
| (x : Term) -> Term
| (x : Term) => Term
| Term Term;
-----------
Type : Type
A : Type x : A
---------------
x : A
Γ, x : A ⊢ B : Type
-------------------
Γ ⊢ (x : A) -> B : Type
Γ, x : A ⊢ m : B
---------------------------
Γ ⊢ (x : A) => m : (x : A) -> B
m : (x : A) -> B n : A
-----------------------
Γ ⊢ m n : B[x := n]
PiSelf:
Term =
| Type
| x
| (x : Term) -> Term
| (x : Term) => Term
| Term Term
| %self(x). Term
| %fix(x). Term
| %unroll Term;
Γ, x : %self(x). T ⊢ T : Type
-----------------------------
Γ ⊢ %self(x). T : Type
Γ, x : %self(x). T ⊢ m : T
----------------------------
Γ ⊢ %fix(x). m : %self(x). T
Γ ⊢ m : %self(x). T
-------------------------
Γ ⊢ %unroll m : T[x := m]
call f x = f x;
{N M A B}. (f : (x : A N) -> B M) -> (x : N) -> B M;
double = (x : Nat) : Nat => x + x;
id = (A : Type 0) => (x : A) => x;
Array : {
@Array : Type;
make : (n : Nat) -> $Array;
} = {
};
Socket : {
@Socket : Type;
connect : () -> $Socket;
close : (socket : $Socket) -> ();
} = {};
List (A : Type) =
channel : Rc<Channel>;
2 buf : (socket : Socket, nat : Nat 15);
(A : Type)
Channel : {
@Channel : Type;
make : (n : Grade) -> Channel n;
} = {};
M : {
double : (x : Nat) -> Nat;
} = {
double = x => x + x;
}
%rec(f : Unit ->! Unit). f ()
Fix = %fix(Fix). Fix -> Never;
Unit = %fix(Unit).
%self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u = %fix(unit). %fix(u). P => x => x;
fix%False (f : %self(f). False f) = (P : False -> Type) -> P f;
False = %self(f). False f;
Unit = %self(u). Unit unit u;
unit : Unit = %unroll unit;
self%Unit : (self%u : %unroll Unit u) -> Type;
self%unit : %unroll Unit unit;
Unit (self%u : %unroll Unit u) = (P : (self%u : %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : (self%u : %unroll Unit u) -> Type) => (x : P unit) => x;
fix%M : {
self%Unit : (self%u : %unroll Unit u) -> Type;
self%unit : %unroll Unit unit;
} = {
Unit (self%u : %unroll M.Unit u) = (P : (self%u : %unroll M.Unit u) -> Type) -> P M.unit -> P u;
unit = (P : (self%u : %unroll M.Unit u) -> Type) => (x : P unit) => x;
};
(u : %self(u). %unroll Unit u) -> Type
expected : (P : (%self(u). %unroll Unit u) -> Type) -> P unit -> P unit
received : (P : (%self(u). %unroll Unit u) -> Type) -> P unit -> P unit
expected : %self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => x => x) -> P u
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => x => x) -> P u
expected : %self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u
received : %self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u
Value -> Value;
Type -> Value;
Type -> Type;
Value -> Type;
Consistency = Soundness + Strong Normalization;
(x : Int) => x;
Never = (A : Type) -> A;
id = (x : Int) => x;
id = (A : Type) => (x : A) => x;
Id = (A : Type) => A;
fold : (A : Type) -> (l : List A) ->
(K : Type) -> (cons : K -> A -> K) -> (nil : K) -> K;
List A = (K : Type) -> (cons : K -> A -> K) -> (nil : K) -> K;
cons {A} el tl : List A = K => cons => nil => cons (tl K cons nil) el;
nil {A} el tl : List A = K => cons => nil => nil;
one_two_three = cons 1 (cons 2 (cons 3 nil));
one_two_three = K => cons => nil => cons (cons (cons nil 3) 2) 1;
x = one_two_three Int (acc => el => acc + el) 0;
if : (pred : Bool) -> (A : Type) -> (then : A) -> (else : A) -> A;
if pred return Int then 1 else 2
if pred return String then "a" else "b"
Bool = (A : Type) -> (then : A) -> (else : A) -> A
Unit = (A : Type) -> (x : A) -> A;
unit : Unit = A => x => x;
Bool = (A : Type) -> (then : A) -> (else : A) -> A;
true : Bool = (A : Type) => (then : A) => (else : A) => then;
false : Bool = A => then => else => else;
not : Bool -> Bool = pred => pred Bool false true;
Nat = (A : Type) -> (zero : A) -> (succ : A -> A) -> A;
zero : Nat = A => zero => succ => zero;
succ : Nat -> Nat = n => A => zero => succ => succ (n A zero succ);
Eq A x y = (P : A -> Type) -> P x -> P y;
refl A x : Eq A x x = (P : A -> Type) => (p : P x) => p;
Neq A x y = (eq : Eq A x y) -> Never;
_ : (n : Nat) -> Neq Nat n (succ n) = _;
_ : Eq Bool true (not false) = refl Bool true;
Eq Bool true true
call_id = (id : (A : Type) -> A -> A) => (id Int 1, id String "a");
fold : (n : Nat) -> (A : Type) -> A -> (A -> A) -> A;
nat_ind : (n : Nat) ->
(P : Nat -> Type) -> P z -> ((pred : Nat) -> P pred -> P (s pred)) -> P n;
fold n A (z : A) (s : A -> A) = nat_ind n (_ => A) z (_ => s);
Nat =
(P : Nat??? -> Type) -> P (z : Nat) -> ((pred : Nat???) -> P pred -> P (s pred)) -> P n???;
Unit = %fix(Unit).
%self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
unit : Unit = %fix(u). P => x => x;
Eq A x y = (P : A -> Type) -> P x -> P y;
%unroll unit : (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P unit
x = unit (_ => Int);
%self(u). (P : T -> Type) -> P u -> P u
(%fix(u). (P : T -> Type) => (x : P u) => x) :
(P : T -> Type) -> P u -> P u;
(%unroll )
Nat = %fix()
forall P : nat -> Type,
P 0 ->
(forall n : nat, P n -> P (S n)) -> forall n : nat, P n
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u) (u : %self(u). %unroll Unit unit u)
= (P : (%self(u). %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u = %fix(unit). %fix(u). P => x => x;
self%Unit : (self%u : %unroll Unit u) -> Type;
self%unit : %unroll Unit unit;
Unit (self%u : %unroll Unit u) =
(P : (self%u : %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : (self%u : %unroll Unit u) -> Type) => (x : P unit) => x;
self%Bool : (self%b : %unroll Bool b) -> Type;
self%true : %unroll Bool true;
self%false : %unroll Bool false;
Bool (self%b : %unroll Bool b) =
(P : (self%b : %unroll Bool b) -> Type) -> P true -> P false -> P b;
true = (P : (self%b : %unroll Bool b) -> Type) =>
(then : P true) => (else : P false) => then;
false = (P : (self%b : %unroll Bool b) -> Type) =>
(then : P true) => (else : P false) => else;
fix%False = %self(f). (P : False -> Type) -> P f;
fix%False (self%f : False f) = (P : (self%f : False f) -> Type) -> P f;
False = %fix(False). %self(f). (P : %unroll False -> Type) -> P f;
expected : %unroll False
received : %self(f). (P : %unroll False -> Type) -> P f
T = %fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f;
False = %self(f).
(P : (self%f : %unroll (
%fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f
) f) -> Type) -> P f;
False = %fix(False). %self(f). (P : %unroll False -> Type) -> P f;
False = %self(f). %unroll (
%fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f
) f;
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
%self(Unit). (a : %self(b). %unroll Unit b b) ->
(u : %self(u). %unroll Unit a u) -> Type;
%self(b). (%unroll Unit b) b
expecetd : %unroll Unit b c
received : %unroll Unit c c
%self(Unit). (a : %self(b). %unroll Unit b b) ->
(u : %self(u). %unroll Unit a u) -> Type
%unroll Unit b
expected : %unroll Unit unit unit
received : %unroll Unit a unit
fix%Unit (self%unit : %unroll Unit unit unit)
(self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
Unit = %self(u). %unroll (
%fix(Unit). (self%u : %unroll Unit u) =>
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(unit). P => (x : P unit) => x) ->
P u
) u;
Unit = %fix(Unit).
(P : %unroll Unit -> Type) -> P ? -> P u;
unit = %fix(unit) : %self(u). %unroll Unit unit u.
%fix(u). P => (x : P (%unroll unit)) => (x : P u);
unit = ;
Unit1 = %fix(Unit1). (self%unit : %self(u). %unroll Unit1 unit u) => (self%u : %unroll Unit1 unit u) =>
(P : (self%u : %unroll Unit1 unit u) -> Type) -> P (%unroll unit) -> P u;
Unit2 = %self(u). %unroll (
%fix(Unit1). (self%unit : %self(u). %unroll Unit1 unit u) => (self%u : %unroll Unit1 unit u) =>
(P : (self%u : %unroll Unit1 unit u) -> Type) -> P (%unroll unit) -> P u
) (%fix(A).?) u;
Unit2 = (
(self%unit : %self(u). %unroll Unit1 unit u) => (self%u : %unroll Unit1 unit u) =>
(P : (self%u : %unroll Unit1 unit u) -> Type) -> P (%unroll unit) -> P u
) (%fix(unit). );
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
expected : %unroll (
%fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f
) f
expected : (P : (self%f : %unroll (
%fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f
) f) -> Type) -> P f
received : (P : (self%f : %unroll (
%fix(False). (self%f : %unroll False f) =>
(P : (self%f : %unroll False f) -> Type) -> P f
) f) -> Type) -> P f
expected : (P : (self%f : %unroll T f) -> Type) -> P f
received : (P : (self%f : %unroll T f) -> Type) -> P f
%self(f). %unroll (%(P : %unroll False -> Type) -> P f)
expected : %unroll False
received : %self(f). %unroll (%fix(False). (P : %unroll False -> Type) -> P f)
False = %self(f).
(P : (f : %self(f). %unroll (
%fix(False). (P : ? -> Type) -> P f;
)) -> Type) -> P f;
expected : %self(f). (P : (self%f : %unroll False f) -> Type) -> P f
received : %self(f). (P : (self%f : %unroll False f) -> Type) -> P f
fix%Unit (self%u : %unroll Unit u) =
(P : (self%u : %unroll Unit u) -> Type) -> P unit -> P u;
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%Unit (self%unit : %self(u). %unroll Unit unit (%unroll unit)) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
// needs to expand unit inside of unit
fix%unit : %self(u). %unroll Unit unit u =
%fix(u). P => (x : P (%unroll u)) => x;
fix%unit (u : %self(u). %unroll Unit unit u)
: %self(u). %unroll Unit unit u =
P => (x : P (%unroll unit)) => (x : P u);
u = %fix(u) : %unroll Unit unit u. %unroll unit u;
expected : %unroll Unit unit u
received :
fix%unit : %self(u). %unroll Unit unit (%fix(u) : %unroll Unit unit u. P => (x : ) => ) =
%fix(u). P => (x : P (%unroll unit)) => (x : P (%unroll unit));
%self(u). %unroll Unit (%fix(unit). u) u
expected : %unroll Unit unit u
received : (P : (self%u : %unroll Unit unit u) -> Type) -> P u -> P u
expected : %self(u). (P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u
received : %self(u). (P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P (%unroll unit)
fix%u : %unroll Unit unit u
= (P : (self%u : %unroll Unit unit u) -> Type) =>
(x : P (%unroll unit u)) => (x : P u)
Unit = %self(u). Unit unit u;
expected : P (%unroll unit u) -> P u
received : P u -> P u
fix%unit : %self(u). %unroll Unit unit u =
%fix(u). P => (x : P (%unroll unit)) => (x : P u);
expected : (x : P (%fix(u). P => x => x)) -> P u
received : (x : P u) -> P u;
expected : %self(u). (P : (self%u : %unroll Unit unit u) -> Type) -> P unit -> P u
received : %self(u). (P : (self%u : %unroll Unit unit u) -> Type) -> P u -> P u
fix%unit (self%u : %unroll Unit (%unroll unit u) u) =
(P : (self%u : %unroll Unit (%unroll unit u) u) -> Type) =>
(x : P (%unroll unit u)) => (%unroll u P x : P u);
u : %self(u). %unroll Unit (%unroll unit u) u
= %fix(u). %unroll unit u;
fix%unit : %self(u). %unroll Unit unit u =
expected : (P : (self%u : %unroll Unit u) -> Type) -> P unit -> P unit
received : (P : (self%u : %unroll Unit u) -> Type) -> P unit -> P unit
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
%self. (%self. %unroll \1 \0 \0) -> (%self. %unroll \2 \1 \0) -> Type;
%self(Unit). (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type;
(%unroll Unit : (a : %self(b). %unroll Unit b b) -> (c : %self(d). %unroll Unit a d) -> Type) b b
(%unroll Unit b : (c : %self(d). %unroll Unit b d) -> Type) b
%fix. (%self. %unroll \1 \0 \0) => (%self. %unroll \2 \1 \0) =>
((%self. %unroll \3 \2 \0) -> Type) -> \0 \2
(\0 : (%self. %unroll \3 \2 \0) -> Type) (\2 : %self. %unroll \3 \0 \0)
expected : %unroll \3 \2 \2
received : %unroll \3 \2 \2
fix%Unit (self%unit : %unroll Unit unit unit) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%Unit (a : %self(b). %unroll Unit b b) (c : %self(d). %unroll Unit a d) =
(P : (e : %self(f). %unroll Unit a f) -> Type) -> P (%coerce a) -> P u;
Γ ⊢ m : %self(x). T
-------------------------
Γ ⊢ %unroll m : T[x := m]
Γ ⊢ m : %self(x). A A[x := m] == B[x := m]
--------------------------------------------
Γ ⊢ %coerce m : %self(x). B
(%unroll (%coerce m : B))
fix%Unit (self%unit : %unroll Unit unit unit) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(u).
%coerce (x => %self(y). %unroll Unit x y)
unit : %self(b). %unroll Unit b b = %fix(b). P => x => x;
expected :
expected : %unroll Unit unit (%unroll u)
received :
self%Unit : (self%u : %unroll Unit u) -> Type;
self%unit : %unroll Unit unit;
Unit (self%u : %unroll Unit u) =
(P : (self%u : %unroll Unit u) -> Type) -> P unit -> P u;
unit =
(f : rec F. F -> ()) => f(f);
rec F. F -> ()
(rec F. F -> ()) -> ()
((rec F. F -> ()) -> ()) -> ()
fix = f => f (fix f);
y = fix fix;
map map = f => l => (l | [] -> [] | el :: tl -> f el :: map map f l);
map = (f => f (fix f)) (fix (f => f (fix f))) map;
map = (f => f (fix f)) map;
[]
y = f => (x => f(x(x)))(x => f(x(x)));
z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));
z(self => 1);
double = x => x + x;
double((() => {
console.log("hi");
return 1;
})())
double(1)
1 + 1
map2 = map map;
(f => f f)(f => f f)
l = map map (+ 1) [1, 2, 3];
l = (+ 1) 1 :: (+ 1) 2 :: (+ 1) 3 :: [];
map = map map [1, 2, 3];
Unit = %self(u). Eq Unit unit u;
False = %fix(False). %self(f). (P : %unroll False -> Type) -> P f
False = %self(f). %unroll (
%fix(False). (f : %self(f). %unroll False f) =>
(P : (f : %self(f). %unroll False f) -> Type) -> P f;
) f;
fix%M : {
Unit : %self(Unit). (u : %self(u). %unroll Unit u) -> Type;
unit : %self(u). %unroll Unit u;
} = {
Unit (u : %self(u). %unroll M.Unit u) =
(P : (u : %self(u). %unroll M.Unit u) -> Type) -> P M.unit -> P u;
unit = (P : (u : %self(u). %unroll M.Unit u) -> Type) => (x : P M.unit) => x;
};
ind_unit : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u;
Unit = (P : Unit -> Type) -> P unit -> P u;
False = %fix(False). %self(f).
(P : %unroll False -> Type) -> P f;
expected : %unroll False;
received : %self(f). (P : %unroll False -> Type) -> P f;
Unit = %ind(Unit, unit : Unit);
fix%False = %self(f). (P : %unroll False -> Type) -> P f;
fix%Unit =
%self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => (x : P u) => x) -> P u;
expected : %self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => (x : P u) => x) -> P u
received : %self(u). (P : %unroll Unit -> Type) -> P (%fix(u). P => (x : P u) => x) -> P u;
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%unit : %self(u). %unroll Unit unit u.
%fix(u). P => (x : P (%unroll unit)) => (x : P u);
P (%unroll unit) == P u;
%unroll unit = u
%fix(unit). P => x => x;
%unroll unit ()
%self().
Unit =
x => y => x
lambda. lambda. \1
x => y => y
lambda. lambda. \0
Teika -> JS
Teika -> Smol
expected : %unroll False
received : %self(f). (P : %unroll False -> Type) -> P f
False = %fix(False). %self(f). (P : False -> Type) -> P f;
f : False;
(P : False -> Type) -> P f
expected : %self(f). (P : False -> Type) -> P f;
received : %self(f). (P : False -> Type) -> P f;
(n : Nat) =>
n |
incr = x => x + 1;
(x => x + 1)
1 + 1 -> generalizes to (x => x + 1) ->
(x => x + 1)(1)
(1 + 1)
(x => x + 1)(2)
(2 + 1)
x => x + 1
(x => M)(N) === M[x := N]
(<A>M)<N> === M[A := N]
(x => x + 1)(1) === (x + 1)[x := 1] => 1 + 1
incr = (x : Int) => x + 1;
id_int = (x : Int) => x;
id_string = (x : String) => x;
((x : Int) => x)
id = <A>(x : A) => x;
id_int = id<Int>;
id_int = (x : Int) => x;
id_string = (x : String) => x;
Array A = (n : Nat, ...(n _ (acc => A :: acc) []));
False = %fix(False). %self(f). (P : %unroll False -> Type) -> P f;
%fix(T,
T_eq : %self(T_eq). Eq Type (%unroll T)
(Eq _
(%fix(False, eq : %unroll T). %self(f).
(P : %unroll False -> Type) -> P (%unroll (T_eq (X => X) eq) (False => %unroll False) f)) False)
).
Eq _ (%fix(False, eq : %unroll T). %self(f).
(P : %unroll False -> Type) -> P (%unroll (T_eq (X => X) eq) (False => %unroll False) f)) False;
False_Eq False = %self(eq). %unroll (%fix(Eq_T, self%Eq_T_eq :
Eq _ (%unroll T)
(Eq _ (%fix(False, eq : %unroll T). %self(f). (P : %unroll False -> Type) ->
P (%unroll (%unroll Eq_T_eq (X => X) eq) (False => %unroll False) f)
) False)
).
Eq _ (%fix(False, eq : %unroll T). %self(f). (P : %unroll False -> Type) ->
P (%unroll eq (False => %unroll False) f)
) False;
);
False = %fix(False,
eq
: %self(eq). Eq _ (%self(f). (P : %unroll False -> Type) -> P (%unroll eq (X => X) f)) (%unroll False)
= %fix(eq). P => (x : P (%self(f). (P : %unroll False -> Type) -> P (%unroll eq (X => X) f))) => x
).
%self(f). (P : %unroll False -> Type) -> P (%unroll eq (X => X) f)
Body_T =
%self(Body). (X : %self(X). Type) -> (X_eq _ (%unroll Body X X_eq) (%unroll X)) -> Type;
Make_eq_unroll
(First : )
(Second : Body_T) =
%fix(X, X_eq : %self(X_eq). Eq _ (%unroll Body X X_eq) (%unroll X)).
%unroll Body X X_eq;
False = Make
()
(False => False_eq =>
%self(f). (P : False -> Type) -> P (%unroll False_eq (X => X) P))
x = Make_eq_unroll (%fix(Body, ()). False => False_eq =>
%self(f). (P : False -> Type) -> )
Eq_T_eqT (self%Eq_T : (False : %self(False). Type) -> Type) =
%self(Eq_T_eq). (False : %self(False). Type) ->
Eq _ (%unroll Eq_T False) (
Eq _ (%fix(False, False_eq : %unroll Eq_T False).
%self(f). (P : %unroll False -> Type) ->
P ((%unroll Eq_T_eq False (X => X) False_eq) (False => %unroll False) f)
) False
);
False_EqT =
%fix(
Eq_T,
Eq_T_eq
: %self(Eq_T_eq). (False : %self(False). Type) ->
Eq _ (%unroll Eq_T False) (
Eq _ (%fix(False, False_eq : %unroll Eq_T False).
%self(f). (P : %unroll False -> Type) ->
P ((%unroll Eq_T_eq (X => X) False_eq) (False => %unroll False) f)
) False
)
= _
). False =>
Eq _ (%fix(False, False_eq : %unroll Eq_T). %self(f). (P : %unroll False -> Type) ->
P (%unroll (%unroll Eq_T_eq (X => X) False_eq) (False => %unroll False) f)
) False;
%fix(False, self%eq : %unroll (%fix(Eq_T, self%Eq_T_eq :
Eq _ (%unroll T)
(Eq _ (%fix(False, eq : %unroll T). %self(f). (P : %unroll False -> Type) ->
P (%unroll (%unroll Eq_T_eq (X => X) eq) (False => %unroll False) f)
) False)
).
Eq _ (%fix(False, eq : %unroll T). %self(f). (P : %unroll False -> Type) ->
P (%unroll eq (False => %unroll False) f)
) False;
)).
False = %fix(False)(
self%eq : Eq Type (%self(f). (P : %unroll False -> Type) -> P (%unroll eq P f))
(%unroll False)
= (P : Type -> Type) => (x : P (%self(f). (P : %unroll False -> Type) -> P (%unroll eq P f))) => x;
). %self(f). (P : %unroll False -> Type) -> P (%unroll eq P f);
Unit = %fix(Unit, eq).
%self(u). (P : %unroll Unit -> Type) ->
P (%fix(u))
P (%unroll eq P u)
Unit = %fix(Unit, Unit_eq). %self(u).
(P : %unroll Unit -> Type) ->
P (%fix(unit, unit_eq) : %unroll Unit.
(P : %unroll Unit -> Type) => (x : P unit) => x
) ->
P (%unroll Unit_eq P u);
Unit = %fix(Unit, eq). (self%unit : %self(u). %unroll Unit unit u) => (self%u : %unroll Unit unit u) =>
(P : (self%u : %unroll Unit unit u) -> Type) ->
P (%unroll unit) -> P u;
unit = %fix(unit, unit_eq) : Unit unit.
%fix(u, _). P => (x : P (%unroll unit)) =>
(unit_eq P )
False = %fix(False,
eq : Eq _ False (fix(False, ))
). %self(f).
fix%Unit (unit : %self(unit). %self(u). %unroll Unit unit u)
(self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit = %fix(unit, ).
%fix(u)(
eq : Eq _ (%unroll unit) u = P => (x : P (%unroll unit)) =>
) : %unroll Unit unit u.
P => (x : P (%unroll unit)) => eq P x;
(P : (self%u : Unit unit u) -> Type) => (x : P (%unroll unit)) => x
fix%T =
%self(eq).
Eq (%self(unit). %self(u). Unit unit u) unit
(%fix(unit, eq : T). %fix(u, ()) : Unit unit u.
P => x => (eq (unit => P (%unroll unit)) x : P u))
fix%Unit (self%u : %unroll Unit u) : Type =
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u) : %unroll Unit u. P => (x : P u) => x) -> P u
fix%Unit (self%u : %unroll Unit u) : Type =
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u) : %unroll Unit u. P => (x : P u) => x) -> P u
TUnit = %self(Unit). (self%u : %unroll Unit u) -> Type;
Tunit_eq (Unit : TUnit) (self%u : %unroll Unit u) =
Eq Type ((P : (self%u : %unroll Unit u) -> Type) -> P u -> P u) (%unroll Unit u);
TUnit_eq (Unit : TUnit) = %self(Unit_eq). (self%u : %unroll Unit u) ->
Eq Type (
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u, u_eq : Tunit_eq Unit u = Unit_eq u).
u_eq (X => X) (P => x => x)) ->
P u
) (%unroll Unit u);
Unit = %fix(Unit, Unit_eq : TUnit_eq Unit = %fix(Unit_eq). P => x => x).
(self%u : %unroll Unit u) =>
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u, u_eq : Tunit_eq Unit u = Unit_eq u).
u_eq (X => X) (P => x => x)) ->
P u;
Unit = %self(u). %unroll Unit u;
unit : Unit = %fix(u, u_eq : Tunit_eq Unit u = Unit_eq u).
u_eq (X => X) (P => x => x);
expected : (P : _) -> P u -> P u
received : %unroll Unit u
case : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
ind_bool : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = %self(b). (P : Bool -> Type) -> P true -> P false -> P b;
T_False_eq False =
%self(False_eq). Eq Type
(%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f))
(%unroll False);
False_eq : %self(False_eq). Eq Type
(%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f))
(%unroll False);
%fix(False,
False_eq : %self(False_eq). Eq Type (%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f)) (%unroll False)
= %fix(False_eq). P => x => x).
%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f);
%self(False_eq). Eq Type
(%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f))
(%self(f). (P : %unroll False -> Type) -> P (%unroll False_eq (X => X) f))
%fix(Fix). (x : %unroll Fix) -> Fix;
Unit : {
Unit : Type;
unit : Unit;
ind_unit : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u;
} = {};
(Unit, unit, ind_unit) = (
fix%Unit = %self(u). (P : Unit -> Type) -> P (%fix(u). P => x => x) -> P u;
unit = %fix(u). P => x => x;
ind_unit = u => %unroll u;
(Unit, unit, ind_unit);
);
((u : Unit) => ind_unit u (_ => Nat) 1) unit;
TUnit = %self(Unit). (self%u : %unroll Unit u) -> Type;
Tunit_eq (Unit : TUnit) (self%u : %unroll Unit u) =
Eq Type ((P : (self%u : %unroll Unit u) -> Type) -> P u -> P u)
(%unroll Unit u);
TUnit_eq (Unit : TUnit) = %self(Unit_eq). (self%u : %unroll Unit u) ->
Eq Type (
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u, u_eq : Tunit_eq Unit u = %unroll Unit_eq u).
u_eq (X => X) (P => x => x)) ->
P u
) (%unroll Unit u);
Tunit_eq (Unit : TUnit) (self%u : %unroll Unit u) =
Eq Type (P u -> P u)
(%unroll Unit u);
%fix(u, u_eq : Tunit_eq Unit u = ).
P => u_eq (u => P u -> P u) (x => x);
Unit = %fix(Unit, Unit_eq : TUnit_eq Unit = %fix(Unit_eq). P => x => x).
(self%u : %unroll Unit u) =>
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u, u_eq : Tunit_eq Unit u = %unroll Unit_eq u).
u_eq (X => X) (P => x => x)) ->
P u;
Unit = %fix(Unit, Unit_eq : TUnit_eq Unit = %fix(Unit_eq). P => x => x).
(self%u : %unroll Unit u) =>
(P : (self%u : %unroll Unit u) -> Type) ->
P (%fix(u, u_eq : Tunit_eq Unit u = %unroll Unit_eq u).
u_eq (X => X) (P => x => x)) ->
P u;
Unit = %self(u). %unroll Unit u;
unit : Unit = %fix(u, u_eq : Tunit_eq Unit u = Unit_eq u).
u_eq (X => X) (P => x => x);
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit,
self%eq : Eq _ (%unroll unit) (%fix(u, ()). P => x => eq P x)
= P => x => x
). %fix(u, ()). P => x => eq P x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = %unroll unit;
fix%Bool
(self%true : (self%false : %self(b). %unroll Bool true false b) ->
%self(b). %unroll Bool true false b)
(self%false : %self(b). %unroll Bool true false b)
(self%b : %unroll Bool true false b) =
(P : (self%b : %unroll Bool true false b) -> Type) ->
P (%unroll true false) -> P (%unroll false) -> P b;
true : (self%false : %self(b). %unroll Bool true false b) -> %self(b). %unroll Bool true false b =
%fix(true,
self%eq : Eq _ (%unroll true false) (%fix(b, ()). P => x => y => eq P x)
= P => x => x;
). false => %fix(b, ()). P => x => y => eq P x;
false : %self(false). %self(b). %unroll Bool true false b =
%fix(false,
self%eq : Eq _ (%unroll false) (%fix(b, ()). P => x => y => eq P y)
= P => x => x;
). %fix(b, ()). P => x => y => eq P y;
Bool = %self(b). %unroll Bool true false b;
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit,
self%eq : Eq _ (%unroll unit) (%fix(u, ()). P => x => %unroll eq P x)
= %fix(eq). P => x => x
). %fix(u, ()). P => x => %unroll eq P x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = %unroll unit;
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit, eq). %fix(u, ()). P => x => %unroll eq P x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = %unroll unit;
T_unit =
%self(unit).
(self%unit_eq :
Eq _ (%unroll unit) (%fix(u). P => x => %unroll unit_eq P x)) ->
%self(u). %unroll Unit (%fix(unit) : %self(u). %unroll Unit unit u) u;
unit : T_unit.
= %fix(unit). unit_eq => %fix(u). P => (x : P unit) => %unroll unit_eq P x;
expected : (P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u
received : (P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P (%fix(self%u : %unroll Unit unit u, ()). P => x => unit_eq P x)
Eq _ ((P : (self%u : %unroll Unit unit u) -> Type) -> P u -> P u)
((P : (self%u : %unroll Unit unit u) -> Type) -> P u -> P u))
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x : %self(x). T,
eq : %self(eq). (P : T -> Type) -> P (%unroll x) -> P M |- M : T[x := M]
--------------------------------------------------------------------------
%fix(self%x : T, eq). M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
---------------------------------------------------
%unroll (%fix(self%x : T, eq). M) ===
M[x := %fix(self%x : T, eq). M]
[eq := %fix(eq, _). (P : T -> Type) => (x : P M) => x]
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit, eq). %fix(u, _). P => x => %unroll eq P x;
Unit = %self(u). %unroll Unit unit u;
unit : Unit = %unroll unit;
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x : %self(x). T, y : A |- M : T[x := M]
Γ, x : %self(x). T |- N : A[x := %fix(self%x : T, y : A = N). M]
----------------------------------------------------------------
%fix(self%x : T, y : A = N). M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
fix%Bool
(self%true : (self%false : %self(b). %unroll Bool true false b) ->
%self(b). %unroll Bool true false b)
(self%false : %self(b). %unroll Bool true false b)
(self%u : %unroll Bool true false b) =
(P : (self%u : %unroll Bool true false b) -> Type) ->
P (%unroll true false) -> P (%unroll false) -> P b;
unit : %self(true). (self%false : %self(b). %unroll Bool true false b) -> %self(b). %unroll Bool true false b =
%fix(unit, eq). %fix(u, _). P => x => %unroll eq P x;
fix%Nat
(self%zero : (self%succ : %self(n). %unroll Nat zero succ n) ->
%self(n). %unroll Nat zero succ n)
(self%succ : (pred : %self(n). %unroll Nat zero succ n) ->
%self(n). %unroll Nat zero succ n) ->
(self%n : %unroll Nat zero succ n) =
(P : (self%n : %unroll Nat zero succ n) -> Type) ->
P (%unroll zero succ) ->
((pred : %self(n). %unroll Nat zero succ n) -> P pred -> P (%unroll succ pred)) ->
P n;
zero
: %self(zero). (self%succ : %self(n). %unroll Nat zero succ n) -> %self(n). %unroll Nat zero succ n
= %fix(zero, eq). succ => %fix(b, _). P => z => s => %unroll eq (b => P (b succ)) z;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit, eq). %fix(u, _). P => x => %unroll eq P x;
T_F_eq = Eq
_
(%fix(False, F_eq : ?))
%fix(False, F_eq).
%self(f). (P : %unroll False -> Type) -> P (F_eq (False => %unroll False) f);
Unit = %fix(Unit, U_eq).
%self(u).
(P : %unroll Unit -> Type) ->
P (
%fix(unit, u_eq).
P => eq_sym u_eq (u => P u -> P unit) (x => x)
) ->
P (U_eq (Unit => %unroll Unit) u);
%fix((true, false), (T_eq, F_eq))
Bool = %fix(Bool, B_eq).
%self(b).
(P : %unroll Bool -> Type) ->
P (
%fix(true, b_eq).
P => eq_sym b_eq (b => P b -> P false -> P true) (x => y => x)
) ->
P (
%fix(true, b_eq).
P => eq_sym b_eq (b => P b -> P false -> P true) (x => y => x)
) ->
P (U_eq (Unit => %unroll Unit) u)
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit). %fix(u). P => x => eq P x;
%unroll (%fix(T). (self%x : %unroll T x) => Type);
u @-> (P : (a : u @-> @((Unit : Unit @-> (unit : unit @-> u @-> @Unit unit u) -> (u : u @-> @Unit unit u) -> Type, _) @=> (unit : unit @-> u @-> @Unit unit u) => (u : u @-> @Unit unit u) => (P : (a : u @-> @Unit unit u) -> Type) -> (b : P (@unit)) -> P u) unit u) -> Type) -> (b : P (@unit)) -> P u :
u @-> @((Unit : Unit @-> (unit : unit @-> u @-> @Unit unit u) -> (u : u @-> @Unit unit u) -> Type, _) @=> (unit : unit @-> u @-> @Unit unit u) => (u : u @-> @Unit unit u) => (P : (a : u @-> @Unit unit u) -> Type) -> (b : P (@unit)) -> P u) unit u
(FalseT : Type) = %self(False). (f : %self(f). %unroll False f) -> Type;
False0 = %fix(False : FalseT).
f => (P : (f : %self(f). %unroll False0 f) -> Type) -> P f;
False1 = %self(f). %unroll False0 f;
eq : (F : _) ->
Eq _ (%unroll False0)
(f => (P : (f : %self(f). %unroll False0 f) -> Type) -> P f)
= _;
f (f : False1) : %self(f). (P : (f : %self(f). %unroll False0 f) -> Type) -> P f
= eq (T => %self(f). (P : (f : %self(f). T f) -> Type) -> P f) f;
expected : %self(f). %unroll False0 f
received : %self(f). (P : (f : %self(f). %unroll False0 f) -> Type) -> P f;
expected : %self(f). %unroll False0 f
received : %self(f). (P : (f : %self(f). %unroll False0 f) -> Type) -> P f;
eq : (F : _) ->
Eq _ (%unroll (%fix(x, eq). F x eq))
(F (%fix(x, eq). F x eq) refl)
= P => (x : P (%unroll (%fix(x, eq). F x eq))) =>
;
W : %self(W). (x : %self(x). %unroll W x) -> Type;
F :
%self(F).
(x : %self(x). %unroll W x) ->
(eq :
%self(eq). (P : %unroll W x -> Type) ->
P (%unroll x) -> P (%unroll F x eq)) ->
%unroll W x;
%fix_red :
(W : %self(W). (x : %self(x). %unroll W x) -> Type) ->
(F : %self(F).
(x : %self(x). %unroll W x) ->
(eq :
%self(eq). (P : %unroll W x -> Type) ->
P (%unroll x) -> P (%unroll F x eq)) ->
%unroll W x) ->
(P : (x : W (%fix(self%x : %unroll W x, eq). %unroll F x eq)) -> Type) ->
P (%unroll (%fix(self%x : %unroll W x, eq). %unroll F x eq))
P (%unroll F (%fix(self%x : %unroll W x, eq). F x eq) refl);
%fix_red(%fix(self%x : T, eq). M) : %self(x). T
%fix_red(
x = %fix(self%x : T, eq). M,
_ : (P : (a : %self(x). T) -> Type) ->
P (%unroll (%fix(self%x : T, eq). M)) ->
P x
);
%fix_red(
x = %fix(self%x : T, eq). M,
_ : (P : (a : %self(x). T) -> Type) ->
P (%unroll (%fix(self%x : T, eq). M)) ->
P x
) ===
(P : (a : %self(x). T) -> Type) =>
(b : P (%unroll (%fix(self%x : T, eq). M))) =>
(b : P (M[x := %fix(self%x : T, eq). M][y := refl]));
Γ |- M : %self(x). T
Γ, x : %self(x). T |- A : Type Γ |- N : A[x := M]
A[a := %unroll M]
A[a := M[]]
---------------------------------------
%fix_red(x = M, eq : A = N) :
A[x := ]
%self(%fix(x, eq). %unroll F x eq)
(%unroll (%fix(x, eq). F x eq))
F (%fix(x, eq). F x eq) refl
F => Eq _
(%unroll (%fix(x, eq). F x eq))
(F (%fix(x, eq). F x eq) refl)
%fix_red (
)
id = (x : Int) => x;
f = P => (x : P (id 1)) => (x : P 1);
g = P => (x : P (id 1)) => (%beta x : P 1);
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
unit_expand (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : Type -> Type) => (x : P (%unroll Unit unit u)) => %expand x;
unit : %self(unit). (eq : _) -> %self(u). %unroll Unit unit u
%fix(unit). (eq : _) => %fix(u). P => x => eq P x;
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit, eq). %fix(u, _).
eq_sym (unit_expand unit u) (X => X) (P => x => eq P x);
unit : %self(unit). %self(u). %unroll Unit unit u =
%fix(unit, eq). %fix(u, _). P => x => x;
id = (x : Int) => %expand x;
x = (x : P (id 1)) => %beta x ==;
(%unroll (%fix(x, eq). M)) === M[x := %fix(x, eq). M][eq := refl]
%expand x === x
Id = X => X;
fix%False (self%I : (self%f : (P : %unroll False I -> Type) -> P (I f)) -> %unroll False I) =
%self(f). (P : %unroll False I -> Type) -> P (I f);
False = %unroll False (%fix(I). P => x => x);
fix%Unit (self%unit : %self(u). %unroll Unit unit u) (self%u : %unroll Unit unit u) =
(P : (self%u : %unroll Unit unit u) -> Type) -> P (%unroll unit) -> P u;
fix%Unit (I1 : Eq _ (%unroll Unit) _) (self%unit : %unroll Unit I1 unit) = (
W (P : %unroll Unit I1 -> Type) = I1 (U => U I1 -> Type) P;
%self(u). (P : %unroll Unit I1 unit -> Type) -> W P (%unroll unit) -> W P u
);
fix%Unit (I1 : Eq _ (%unroll Unit I1) _) = (
W (P : %unroll Unit I1 -> Type) = I1 (U => U -> Type) P;
fix%unit (I2 : _) = %fix(u). I2 (P => (x : W P (%unroll unit I2)) => x);
unit = %unroll unit (%fix(I2).
(x : ((P : )))
)
%self(u). (P : %unroll Unit I1 -> Type) ->
W P (%unroll unit) -> W P (u)
);
!Unit ===
%self(u). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
%unroll I_Unit unit I_unit P (%unroll unit I_unit) ->
%unroll I_Unit unit I_unit P u;
!T_I_Unit ===
%self(I_Unit). (unit : !T_unit) -> (I_unit : !T_I_unit) ->
(P : %unroll Unit I_Unit unit I_unit -> Type) -> !Unit -> Type;
!T_unit ===
%self(unit). (I_unit : !T_I_unit) -> !Unit;
!T_I_unit ===
%self(I_unit). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
P (%unroll unit I_unit) -> P !unit;
!unit ===
%fix(u). (P : %unroll Unit I_Unit unit I_unit -> Type) =>
(x : P (%unroll unit I_unit)) => %unroll I_unit P x;
fix%Unit (I_Unit : !T_I_Unit) (unit : !T_unit) (I_unit : !T_I_unit) : Type = !Unit;
I_Unit : !T_I_Unit = %fix(I_Unit). unit => I_unit => P => %expand P;
fix%unit (I_unit : !T_I_unit) : !Unit = !unit;
I_unit : !T_I_unit = %fix(I_unit). P => %expand P;
Unit = %unroll Unit I_Unit unit I_unit;
!Unit ===
%self(u). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
P (%unroll unit I_unit) -> %unroll I_Unit unit I_unit P u;
!T_I_Unit ===
%self(I_Unit). (unit : !T_unit) -> (I_unit : !T_I_unit) ->
(P : %unroll Unit I_Unit unit I_unit -> Type) -> !Unit -> Type;
!T_unit ===
%self(unit). (I_unit : !T_I_unit) -> %unroll Unit I_Unit unit I_unit;
!T_I_unit ===
%self(I_unit). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
%unroll I_Unit unit I_unit P (%unroll unit I_unit) ->
%unroll I_Unit unit I_unit P !unit;
!unit ===
%fix(u). (P : %unroll Unit I_Unit unit I_unit -> Type) =>
(x : P (%unroll unit I_unit)) => %unroll I_unit P x;
fix%Unit (I_Unit : !T_I_Unit) (unit : !T_unit) (I_unit : !T_I_unit) : Type = !Unit;
I_Unit : !T_I_Unit = %fix(I_Unit). unit => I_unit => P => %expand P;
fix%unit (I_unit : !T_I_unit) : !Unit = !unit;
I_unit : !T_I_unit = %fix(I_unit). P => %expand P;
Unit = %unroll Unit I_Unit unit I_unit;
FalseT = %self(False).
(I_False : %self(I_False).
(P : %unroll False I_False -> Type) ->
(%self(f). (P : %unroll False I_False -> Type) -> I_False P f) -> Type)
-> Type;
fix%False (I_False : ) =
%self(f). (P : %unroll False I_False -> Type) -> I_False P f;
%self(u). (P : %unroll Unit I_Unit unit I_unit -> Type) -> P (%unroll unit I_unit) -> P u
fix%Unit (unit : T_unit) (I_unit : T_I_unit) =
%self(u). (P : T unit I_unit -> Type) ->
P (%unroll unit I_unit) -> P u;
fix%unit I1 : %self(u). (P : T unit I1 -> Type) -> P (%unroll unit I1) -> P u =
%fix(u). (P : T unit I1 -> Type) => (x : P (%unroll unit I1)) => I1 P x;
expected : (P : _ -> Type) -> P (%unroll unit I1) -> P u
received : (P : _ -> Type) -> P (%unroll unit I1) -> P (%fix(u). (P : _ -> Type) => (x : P (%unroll unit)) => I1 P x)
unit =
(self%I : (f : %self(f). (P : %unroll False I -> Type) -> P (I f)) -> %unroll False I) =>
%self(f). (P : %unroll False I -> Type) -> P (I f)
Γ, x : %self(x). T |- T : Type
------------------------------
%self(x). T : Type
Γ, x : %self(x). T |- M : T[x := %fix(x) : T. M]
------------------------------------------------
%fix(x) : T. M : %self(x). T
Γ |- M : %self(x). T
---------------------
%unroll M : T[x := M]
Γ |- N : P (%unroll (%fix(x) : T. M))
---------------------------------------
%expand(N) : P (M[x := %fix(x) : T. M])
----------------
%expand(N) === N
!Unit ===
%self(u). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
%unroll I_Unit unit I_unit P (%unroll unit I_unit) ->
%unroll I_Unit unit I_unit P u;
!T_I_Unit ===
%self(I_Unit). (unit : !T_unit) -> (I_unit : !T_I_unit) ->
(P : %unroll Unit I_Unit unit I_unit -> Type) -> !Unit -> Type;
!T_unit ===
%self(unit). (I_unit : !T_I_unit) -> !Unit;
!T_I_unit ===
%self(I_unit). (P : %unroll Unit I_Unit unit I_unit -> Type) ->
%unroll I_Unit unit I_unit P (%unroll unit I_unit) ->
%unroll I_Unit unit I_unit P !unit;
!unit ===
%fix(u). (P : %unroll Unit I_Unit unit I_unit -> Type) =>
(x : P (%unroll unit I_unit)) => %unroll I_unit P x;
fix%Unit (I_Unit : !T_I_Unit) (unit : !T_unit) (I_unit : !T_I_unit) : Type = !Unit;
I_Unit : !T_I_Unit = %fix(I_Unit). unit => I_unit => P => %expand P;
fix%unit (I_unit : !T_I_unit) : !Unit = !unit;
I_unit : !T_I_unit = %fix(I_unit). P => %expand P;
!Unit =
%self(u). (P : %unroll Unit I_Unit I_unit -> Type) ->
%unroll I_Unit I_unit P !unit ->
%unroll I_Unit I_unit P u;
!unit =
%fix(unit). (P : %unroll Unit I_Unit I_unit -> Type) =>
(x : %unroll I_Unit I_unit P unit) => x;
!T_I_unit ===
%self(I_unit). (P : %unroll Unit I_Unit I_unit -> Type) ->
%unroll I_Unit I_unit P (%unroll unit I_unit) ->
%unroll I_Unit I_unit P !unit;
!T_I_Unit =
%self(I_Unit). (I_unit : !T_I_unit) ->
(P : %unroll Unit I_Unit I_unit -> Type) -> !Unit -> Type;
fix%Unit I_Unit I_unit =
%self(u). (P : %unroll Unit I_Unit I_unit -> Type) ->
%unroll I_Unit I_unit P !unit ->
%unroll I_Unit I_unit P u;;
!Unit =
%self(u). (P : %unroll Unit I_Unit unit -> Type) ->
P (%unroll unit) -> %unroll I_Unit unit P u
!T_unit = %self(unit). %unroll Unit I_Unit unit;
!T_I_Unit =
%self(I_Unit). (unit : !T_unit) ->
(P : %unroll Unit I_Unit unit -> Type) -> !Unit -> Type;
fix%Unit I_Unit unit = !Unit;
fix%I_Unit (unit : !T_unit) = P => P;
fix%unit : !T_unit =
%fix()
fix%I_Unit unit
!Unit =
%self(u). (P : %unroll Unit I_Unit -> Type) ->
%unroll I_Unit P !unit -> %unroll I_Unit P u;
!unit =
%fix(unit). (P : %unroll Unit I_Unit -> Type) =>
(x : %unroll I_Unit P unit) => x;
!T_I_Unit =
%self(I_Unit). (P : %unroll Unit I_Unit -> Type) -> !Unit -> Type
!T_Unit =
%self(Unit). (I_Unit : !T_I_Unit) -> Type;
Unit = %unroll Unit I_Unit unit I_unit;
!Unit =
%self(u). (P : %unroll Unit I_Unit -> Type) ->
%unroll I_Unit P !unit -> %unroll I_Unit P u;
!unit =
%fix(unit). (P : %unroll Unit I_Unit -> Type) =>
(x : %unroll I_Unit P unit) => x;
!T_I_Unit =
%self(I_Unit). (P : %unroll Unit I_Unit -> Type) -> !Unit -> Type
!T_Unit =
%self(Unit). (I_Unit : !T_I_Unit) -> Type;
Unit I_Unit u = (
fix%unit I_unit = %fix(unit). I_unit =>
%fix(u). (P : %unroll Unit I_Unit -> Type) ->
(x : %unroll I_Unit P (%unroll unit)) => %unroll I_unit P x;
%self(u). (P : %unroll Unit I_Unit -> Type) ->
%unroll I_Unit P unit -> %unroll I_Unit P u
);
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
fix%Bool = %self(b). (P : Bool -> Type) -> P true -> P false -> P b;
ind (b : Bool) = %unroll b;
fold : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
fold (b : Bool) = b;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
fold : (n : Nat) -> (A : Type) -> A -> (A -> A) -> A;
Nat = (A : Type) -> A -> (A -> A) -> A;
zero : Nat = A => z => s => z;
succ (n : Nat) : Nat = A => z => s => s (n A z s);
received: (I_Unit : (I_UnitT : (Unit : UnitT : Type) -> Type) (Unit : UnitT : Type)) -> Type
expected: (I_Unit : (I_UnitT : Type) (Unit : UnitT : Type)) -> Type
fix%Eq A x y = (
refl A x : Eq A x x = %fix(eq). P => x => x;
// use equality to ensure that y is equal to x inside of P
%self(eq). (P : (y : A) -> Eq A x y -> Type) -> P x (refl A x) -> P y eq
);
refl A x : Eq A x x = %fix(eq). P => x => x;
uip_refl_on A x (eq : Eq A x x) =
(P : Eq A x x -> Type) => (x : P eq) =>
%unroll eq (y => eq => P (eq (y => Eq A y x) (refl A y)));
Eq _ eq (eq (y => Eq A x y) (refl A x))
Eq _ (refl A x) ((refl A x) (y => Eq A x y) (refl A x))
Eq _ (refl A x) (refl A x)
a A a === b A b
%self(refl). (A : Type) -> (x : A) ->
%self(eq). (P : Eq A x x -> A -> Type) -> P (refl A x) x -> P eq x
fix%refl A x
: %self(eq). (P : Eq A x x -> Type) -> P (refl A x) -> P eq =
%fix(eq). (P : Eq A x x -> Type) => P () -> P eq;
fix%False (I_False) =
%self(f). (P : %unroll False I_False) -> P (%unroll I_False Id f);
%self(I). Eq _ (%unroll T I) (%unroll B refl T I);
!Unit =
%self(u). %unroll Unit0 unit0 I_unit u;
!Unit0 =
(P : (u : !Unit) -> Type) -> P (%unroll unit0 I_unit) -> P u;
!unit0 =
%fix(u : !Unit0). (P : (u : !Unit0) -> Type) =>
(x : P (%unroll unit0 I_unit)) => %unroll I_unit P x;
!T_I_unit =
%self(I_unit). (P : (u : !Unit0) -> Type) ->
P (%unroll unit0 I_unit) -> P !unit0
!T_unit0 =
%self(unit0). (I_unit : !T_I_unit) -> !Unit0;
!T_unit0 =
%self(unit0). (I_unit : !T_I_unit) -> !Unit0;
!T_Unit0 =
%self(Unit0). (unit0 : !T_unit0) -> (I_unit : !T_I_unit) ->
(u : !Unit) -> Type;
fix%Unit0 unit0 I_unit (u : !Unit) = !Unit;
fix%unit0 I_unit = !unit0;
fix%I_unit = P => P;
Unit = %self(u). %unroll Unit0 unit0 I_unit u;
unit : Unit = %unroll unit0;
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
!Unit0 =
u @-> (P : Unit -> Type) -> (x : P (@IT unit)) -> P (@IT u);
!T_IT =
IT @-> !Unit0 -> Unit;
!unit0 = (u : !Unit0) @=> (P : Unit -> Type) => (x : P unit) => @I1 P x;
!T_I1 = I1 @-> (P : Unit -> Type) -> (x : P unit) -> P (!unit0);
Unit0 (Unit : Type) (IT : !T_IT) (unit : Unit) = !Unit0;
unit0 (Unit : Type) (unit : Unit) (I1 : !T_I1) = !unit0;
!Unit =
u @-> @Unit0 IT unit I1;
!Unit0 =
u @-> (P : !Unit -> Type) ->
(x : @IT unit I1 P (@unit I1)) -> @IT unit I1 P u;
!IT
!unit0 =
(u : !Unit0) @=> (P : !Unit -> Type) =>
(x : @IT unit I1 P (@unit I1)) => @I1 P x;
!I1
!T_I1 =
I1 @-> (P : !Unit -> Type) -> (x : P (@IT unit)) -> P (!unit0)
!T_unit =
unit @-> (I1 : !T_I1) -> !Unit0;
!T_IT =
IT @-> (unit : !T_unit) -> (I1 : !T_I1) -> (u : !Unit0) -> !Unit;
!T_Unit0 =
Unit0 @-> ()
!T_Unit = Type;
Unit =
Unit @=> (IT : !T_IT)
(unit : unit @-> (I1 : !T_I1) -> Unit IT unit I1) (I1 : !T_I1)
= Unit0 (Unit IT unit I1) IT (IT (@unit I1));
IT = _;
fix%unit (I1 : !T_I1) = unit0 (Unit IT unit I1) unit I1;
%self(I1). (P : Unit -> Type) -> P unit ->
P (IT )
%fix(u). (P : Unit -> Type) => (x : P unit) =>
fix%False IT =
%self(f). (P : %unroll False IT -> Type) -> %unroll IT P f;
%fix. _A =>
%self. (%unroll \2 \1 -> Type) -> %unroll \2 \0 \1;
_A := %self. _B
%unroll \2 : _B[\0 := \2]
expected : (%unroll \1 \0 -> Type) -> _C
received : _B[\0 := \2]
%unroll \2 \0 :
IT : %self. (%unroll \1 \0 -> Type) ->
IT : _A
_A := %self(x). _B
(A : Type\0) => (x : A\0) => (x\0 : A\1)
%unroll IT :_B[x := IT]
(P : %unroll False IT -> Type) -> _C `unify` _B[x := IT]
_B := (P : %unroll False x -> Type) -> _C;
_C :=
(%self(f). (P : %unroll False x -> Type) -> %unroll x P f) -> Type
((P : %unroll False IT -> Type) -> _C)[x := IT]
M : _A
%unroll M : _A[]
fix%False IT =
%self(f). (P : %unroll False IT -> Type) -> %unroll IT P f;
%fix(False). (IT : _A) =>
%self(f). (P : %unroll False IT -> Type) -> %unroll IT P f
(%unroll IT) (P : %unroll False IT -> Type) f
fix%False (IT : _A) =
%self(f). (P : %unroll False IT -> Type) -> %unroll IT P f;
IT : _A
%unroll IT : _B[x := IT]
_A := %self(x). _B
%unroll IT P : _C[x := IT]
_B := (P : %unroll False x -> Type) -> _C
%unroll IT P f : Type
_C := (%self(f). (P : %unroll False x -> Type) -> %unroll x P f) -> Type;
fix%False (IT : _A)=
%self(f). (P : %unroll False\2 IT\1 -> Type) -> %unroll IT\2 P\0 f\1;
IT\2 : _A[+2]
%unroll IT\2 : _B[IT\2][-2]
_A : %self(x). _B[+1]
%unroll IT\2 P\0 : _C[IT\2][-2]
_B := ((P : %unroll False\2 IT\1 -> Type) -> _C)[IT\2][-2]
%unroll IT\2 P\0 f\1 : Type
_C := ((%self(f). (P : %unroll False\2 IT\1 -> Type) -> %unroll IT\2 P\0 f\1) -> Type)
fix%Unit IT unit I1 =
%self(u). (P : %unroll Unit IT unit I1 -> Type) ->
%unroll IT unit I1 (%unroll unit I1) -> %unroll IT unit I1 u;
Unit = %unroll Unit (%fix(IT). P => x => %expand x);
fix%unit I1 : %unroll Unit unit I1 = P => x => %unroll I1 P x;
Unit = Unit unit (%fix(I1). P => x => %expand x);
unit : Unit = unit _;
fix%Bool IT true I1 false I2 = (
IT = %unroll IT true I1 false I2;
Bool = %unroll Bool IT true I1 false I2;
true = %unroll true I1 false I2;
false = %unroll false I2;
%self(b). (P : Bool -> Type) -> IT P true -> IT P false -> IT P b
);
fix%Unit IT unit I1 =
%self(u). (P : %unroll Unit IT unit I1 -> Type) ->
P (%unroll IT unit I1 (%unroll unit I1)) ->
P (%unroll IT unit I1 u);
f = (x : _A) => (P : x) -> %unroll x\1 x\1
_A := %self(y). _B
%unroll x\1 : _B[-1][x\1]
fix%False (IT : _A)=
%self(f). (P : %unroll False\2 IT\1 -> Type) -> %unroll IT\2 P\0 f\1;
%unroll (IT\2 : _A[2]) : _B[-2][IT\2]
_A[2] `unify` %self(x). _B
_A := %self(x). _B[-2]
fix%False (IT : _A)=
%self(f). (P : %unroll False\1 IT\2 -> Type) -> %unroll IT\2 P\4 f\3;
%unroll IT\2 : _B
_A := %self(x). _B
%unroll IT\2 P : _C
_B := (P : %unroll False\1 IT\2 -> Type) -> _C
%unroll IT\2 P\4 f\3 : Type
_C := (%self(f). (P : %unroll False\1 IT\2 -> Type) -> %unroll IT\2 P\4 f\3) -> Type;
%self(x). (P : %unroll False\1 IT\2 -> Type) -> (%self(f). (P : %unroll False\1 IT\2 -> Type) -> %unroll IT\2 P\4 f\3) -> Type
(x : _A) => (f : _B) => f\0 x\1
f\0 : _C -> _D
_B := (_C -> _D)[0]
x\1 : _C
_C := _A[1]
f\0 : _A[1] -> _D
!Unit =
%self
fix%Unit IT
!False = %self(f). (P : %unroll False IT -> Type) -> %unroll IT P f;
!IT_T = %self(IT). (P : %unroll False IT -> Type) -> !False -> Type;
fix%False (IT : !IT_T) = !False;
!Unit =
%self(u). (P : %unroll Unit IT unit I1 -> Type) ->
%unroll IT unit I1 P (%unroll unit I1) -> %unroll IT unit I1 P u;
!unit =
%fix(u). (P : %unroll Unit IT unit I1 -> Type) =>
%unroll I1 P ((x : %unroll IT unit I1 (%unroll unit I1)) => x);
!T_IT =
%self(IT). (P : %unroll Unit IT unit I1 -> Type) -> !Unit -> Type;
!T_I1 =
%self(I1). Eq _ (%unroll unit I1) !unit;
fix%Unit (IT : !T_IT) (unit : !T_unit) (I1 : !T_I1) = !Unit;
fix%Unit IT = (
fix%unit
(I1 : %self(I1). (P : %unroll Unit IT -> Type) -> %unroll IT P (%unroll unit I1) -> %unroll IT P u)
= %fix(u)
: (P : %unroll Unit IT -> Type) -> %unroll IT P (%unroll unit I1) -> %unroll IT P u
. (P : %unroll Unit IT -> Type) => %unroll I1 P ((x : %unroll IT P u) => x);
%self(u). (P : %unroll Unit IT -> Type) -> %unroll IT P unit -> %unroll IT P u
);
!unit =
%fix(u)
: (P : %unroll Unit IT -> Type) ->
(x : %unroll IT P (%unroll unit I1)) => %unroll IT P u
. (P : %unroll Unit IT -> Type) =>
(x : %unroll IT P (%unroll unit I1)) => %unroll I1 P x;
!Unit =
%self(u). (P : %unroll Unit IT -> Type) ->
%unroll IT P (%unroll unit I1) -> %unroll IT P u;
!T_IT =
%self(IT). (P : %unroll Unit IT -> Type) -> !Unit -> Type;
!T_I1 =
%self(I1). (P : %unroll Unit IT -> Type) ->
%unroll IT P (%unroll unit I1) -> %unroll IT P !unit;
!T_unit =
%self(unit). (I1 : !T_I1) -> !Unit;
fix%Unit (IT : !T_IT) = (
unit = %fix(unit : !T_unit). (I1 : !T_I1) => !unit;
I1 = %fix(I1 : !T_I1). (P : %unroll Unit IT -> Type) =>
(x : %unroll IT P (%unroll unit I1)) => %expand x;
!Unit
);
!Unit = %self(u). %unroll Unit0 T_I1 unit0 I1 u;
!unit = %unroll unit0 I1;
!Unit0 =
(P : !Unit -> Type) -> P !unit -> P u;
!T_unit0 =
%self(unit0). (I1 : T_I1) -> !Unit;
!T_Unit0 =
%self(Unit0). (T_I1 : Type) -> (unit0 : !T_unit0) ->
(I1 : T_I1) -> (u : !Unit) -> Type;
!unit0 =
%fix(u) : !Unit0. (P : !Unit -> Type) => (x : P !unit) => %unroll I1 P x;
!T_I1 =
%self(I1). (P : !Unit -> Type) -> P !unit -> P !unit0;
cast : (%self(u). !Unit0) -> !Unit;
fix%Unit0 T_I1 unit I1 u = !Unit0;
fix%unit0 I1
fix%unit I1 = %fix(u) : %unroll Unit unit I1 u.
(P : (self%u : %unroll Unit unit u) -> Type) =>
(x : P (%unroll unit I1)) => %unroll I1 P x;
fix%unit = %unroll unit0
!Unit = %unroll Unit0 FT T_F1 unit0 F1;
!unit = %unroll unit0 F1;
!FT = %unroll FT T_F1 unit0 F1;
!Unit0 =
%self(u). (P : !Unit -> Type) ->
!FT P !unit -> !FT P u;
!unit0 = %fix(u : !Unit0).
(P : !Unit -> Type) => (x : !FT P !unit) =>
!T_FT =
%self(FT). (T_F1 : Type) -> (unit0 : !T_unit0) -> (F1 : T_F1) ->
(P : !Unit -> Type) -> !Unit0 -> Type;
!T_unit0 =
%self(unit0). (F1 : T_F1) -> !Unit0;
!T_Unit0 =
%self(Unit0). (FT : !T_FT) -> (T_F1 : Type) ->
(unit0 : !T_unit0) -> (F1 : T_F1) -> Type;
!T_F1 =
%self(F1). (x : !FT P !unit) -> !FT P !unit0
fix%Unit0 FT T_F1 unit0 F1 = !Unit0;
%self(False, f). (P : False -> Type) -> P f
%self(Unit, u).
UnitT =
%self(A, Unit).
(Eq_A : Eq _ A A) =>
(Eq_Unit : Eq _ Unit (
)) =>
_;
%fix(A, Unit). (Eq_A : Eq _ A UnitT) =>
(Eq_Unit : Eq _ Unit)
Γ, A : Type, x : A |- T : Type
------------------------------
%self(A, x). T : Type
Γ, A : Type, x : A |- T
-----------------------
%self(A, x). T : Type
%self(A, Unit). (unit : A) -> Type;
%fix(A, Unit). W => unit =>
%self(u). (P : Unit W -> Type) -> W P unit -> W P u;
Γ, x : T |- T : Type
------------------------------
%self(x). T : Type
%self(Unit, T).
(eq : %exists(X). Eq _ U Type) ->
Type;
%self(False). (eq : %self(eq). Eq _ (False eq) _) -> Type
%fix(False). (eq : %self(eq). Eq _ _ (False eq)) =>
%self(f). (P : False eq -> Type) -> P (%unroll eq (X => X) f)
%self(False). (f : %self(f). %unroll False f) -> Type;
%fix(U, Unit). (unit : %self) =>
(P : Unit -> Type) -> P u;
Unit W1 W2 = %self(Unit, u). (P : Unit -> Type) -> W1 Unit P u -> W2 Unit P u;
%self(A, x). (P : A -> Type) -> P x;
%unroll (%fix(A, x). A);
%self(A, x). A
fix%False W0 = (
False = %unroll False W0;
W0 = %unroll W0;
%self(f). (P : False -> Type) -> W0 P f;
);
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
// expanded
fix%Unit unit W0 W1 = (
Unit = %unroll Unit unit W0 W1;
unit = %unroll unit W0 W1;
W0 = %unroll W0 W1;
%self(u). (P : Unit -> Type) -> W0 P unit -> W0 P u;
);
fix%unit W0 W1 : %unroll Unit unit W0 W1 = (
Unit = %unroll Unit unit W0 W1;
unit = %unroll unit W0 W1;
W0 = %unroll W0 W1;
W1 = %unroll W1;
%fix(u). (P : Unit -> Type) => (x : W0 P unit) => W1 P x;
);
Unit = %unroll Unit unit (%fix(W0). P => P) (%fix(W1). P => P);
unit : Unit = %unroll unit _ _;
fix%Bool true false W0 W1 W2 = (
Bool = %unroll Bool true false W0 W1 W2;
true = %unroll true false W0 W1 W2;
false = %unroll false W0 W1 W2;
W0 = %unroll W0 W1 W2;
%self(b). (P : Bool -> Type) -> W0 P true -> W0 P false -> W0 P b;
);
fix%unit W0 W1 : %unroll Unit unit W0 W1 = (
Unit = %unroll Unit unit W0 W1;
unit = %unroll unit W0 W1;
W0 = %unroll W0 W1;
W1 = %unroll W1;
%fix(u). (P : Unit -> Type) => (x : W0 P unit) => W1 P x;
);
//
fix%False (W0 : _A) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
_A := %self(x). _B
%unroll W0 : _B[x := W0]
_A :=
%unroll W0\2 : _B[x := W0\2]
_A := %self(x). _B
(A : Type\1) -> A\2
fix%False (W0 : %self(W0).
(P : %unroll False\1 W0\2 -> Type) ->
(f : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4) ->
%unroll False\1 W0\2
) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
fix%False (W0 : _A) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
W0\2 : _A[+2]
_A := %self(x). _B[-2]
%unroll W0\2 : _B[W0\2]
_B := (P : %unroll False\1 W0\2 -> Type) -> _C
%unroll W0\2 P\4 : _C[P\4]
_C := (f : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4) -> Type
%unroll W0\2 P\4 f\3 : Type
%self(x). (P : %unroll False\1 W0\2 -> Type) -> _C[-2]
f => value => f value;
(value : (value : _B))
(value : _B) -> ?
(_A x)[x := 2]
((x => ) y)
fix%Bool true false W0 W1 W2 = (
Bool = %unroll Bool true false W0 W1 W2;
true = %unroll true false W0 W1 W2;
false = %unroll false W0 W1 W2;
W0 = %unroll W0 W1 W2;
W1 = %unroll W1 W2;
W2 = %unroll W2;
%self(b). (P : Bool -> Type) -> W0 P true -> W0 P false -> W0 P b;
);
fix%true false W0 W1 W2 = (
Bool = %unroll Bool true false W0 W1 W2;
true = %unroll true false W0 W1 W2;
false = %unroll false W0 W1 W2;
W0 = %unroll W0 W1 W2;
W1 = %unroll W1 W2;
W2 = %unroll W2;
%fix(b). (P : Bool -> Type) => (x : W0 P true) => (y : W0 P false) => W1 P x;
);
fix%false W0 W1 W2 = (
Bool = %unroll Bool true false W0 W1 W2;
true = %unroll true false W0 W1 W2;
false = %unroll false W0 W1 W2;
W0 = %unroll W0 W1 W2;
W1 = %unroll W1 W2;
W2 = %unroll W2;
%fix(b). (P : Bool -> Type) => (x : W0 P true) => (y : W0 P false) => W2 P y;
);
Bool : Type = %unroll Bool true false (%fix(W0). P => %expand P)
(%fix(W1). P => %expand P) (%fix(W2). P => %expand P);
true : Bool = %unroll true false _ _ _;
false : Bool = %unroll true false _ _ _;
Bool : Type;
true : Bool;
false : Bool;
Bool = %self(b : Bool). (P : Bool -> Type) -> P true -> P false -> P b;
true = (P : Bool -> Type) => (x : P true) => (y : P false) => x;
false = (P : Bool -> Type) => (x : P true) => (y : P false) => y;
fix%False\1 W0\2 =
%self(f\3). (P\4 : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
W0\2 : _A[+2]
_A := (%self(x\2). _B)[-2]
%unroll W0\2 : _B[x\2 := W0\2]
_B := (P\4 : %unroll False\1 W0\2 -> Type) -> _C
%unroll W0\2 P\4 : _C[x\2 := W0\2]
_C := (f : %self(f\3). (P\4 : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3) -> Type;
%unroll W0\2 P\4 f\3 : Type
fix%False\1 (W0\2 : _A) =
%self(f\3). (P\4 : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
W0\2 : _A[-2]
_A := (%self(x). _B)[+2]
%unroll W0\2 : _B[x := W0\2]
(x : _A) => (y : _B) => x;
x : _A[+1]
_A := ((A : Type) -> A\2)[-1];
(x : _A) => (y : _B) => x
fix%False\1 (W0\2 : _A) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
W0\2 : _A[+2]
_A := (%self(x). _B)[-2]
%unroll W0\2 : _B[x := W0\2]
P\4 : %unroll False\1 W0\2 -> Type
_B := (P : %unroll False\1 W0\2 -> Type) -> _C
%unroll W0\2 P\4 : _C[x := W0\2]
f\3 : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\6 f\5
_C := (f : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\6 f\5) -> Type;
%unroll W0\2 P\4 f\3 : Type
fix%False\1 (W0\2 :
%self(W0\2). (P\3 : %unroll False\1 W0\2 -> Type) ->
(f\4 : %self(f\2). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4) -> Type
) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
fix%False\1 (W0\2 : _A) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
W0\2 : _A[+2]
_A := (%self(x). _B[+1])[-2]
%unroll W0\2 : _B[x := W0\2]
P\4 : %unroll False\1 W0\2 -> Type
_B := (P : %unroll False\1 W0\2 -> Type) -> _C[+1]
%unroll W0\2 P\4 : _C[x := W0\2]
f\3 : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4
_C := (f : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4) -> Type
%self(W0).
(P : %unroll False\1 W0\2 -> Type) ->
(f : %self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\5 f\4) -> Type
fix%False (W0 : _A) =
%self(f). (P : %unroll False\2 W0\1 -> Type) -> %unroll W0\2 P\0 f\1;
W0 : _A[+2]
_A := (%self(x). _B[+1])[-2]
%unroll W0\2 : _A[x := W0\2]
_B := (P : %unroll False\2 W0\1 -> Type) -> _C[+1]
%unroll W0\2 P\0 : _C[x := W0\2]
f\1 : %self(f). (P : %unroll False\3 W0\2 -> Type) -> %unroll W0\3 P\0 f\1
_C := (f : %self(f). (P : %unroll False\3 W0\2 -> Type) -> %unroll W0\3 P\0 f\1) -> Type
%self(W0). (P : %unroll False\3 W0\2 -> Type) -> (f : %self(f). (P : %unroll False\5 W0\4 -> Type) -> %unroll W0\5 P\0 f\1) -> Type
fix%False\1 (W0\2 : _A) =
%self(f). (P : %unroll False\1 W0\2 -> Type) -> %unroll W0\2 P\4 f\3;
ind :
%self(ind). (u : Unit) ->
(P : Unit -> (P unit -> P u (%unroll ind u P)) -> Type) ->
P unit (%unroll ind u) -> P u (%unroll ind u P);
%unroll u P (x : P unit) === x
match u with
| I => x
end ===
forall (A : Type) (x : A) (P : forall a : A, eq_t A x a -> Set),
P x (eq_refl A x) -> forall (a : A) (e : eq_t A x a), P a e
eq_ind :
(A : Type) -> (x : A) -> (y : A) -> (eq : Eq a x y) ->
(P : (y : A) -> Eq A x y -> Type) ->
P x (refl A x) -> P y eq
Eq A x y =
%self(eq).
(P : (y : A) -> Eq A x y -> Type) ->
P x (refl A x) -> P y eq;
Eq : (A : Type) -> (x : A) -> (y : A) -> Type;
refl : (A : Type) -> (x : A) -> Eq A x x -> Type;
Eq A x y = %self(eq).
(P : (y : A) -> Eq A x y -> Type) ->
P x (refl A x) -> P y eq
Key : Type;
Frozen : {
@Frozen : (A : Type, k : Key) -> Type;
freeze : {A} -> (k : Key, x : A) -> Frozen(A, k);
unfreeze : {A} -> (k : Key, x : Frozen(A, k)) -> A;
};
Nat_TE = ($Nat_key) => {
// Nat.te
@Nat = Frozen($Nat_key, Int);
zero = Frozen.freeze($Nat_key, Int.zero);
one = Frozen.freeze($Nat_key, Int.one);
add = (n, m) => {
n = Frozen.unfreeze($Nat_key, n);
m = Frozen.unfreeze($Nat_key, m);
Int.add(n, m)
};
}
Nat_TEI = {
// Nat.tei
@Nat : Type;
zero : @Nat;
one : @Nat;
add : (n : @Nat, m : @Nat) ->
};
M_TE = ($Nat_key, $M_key) => {
Nat : Nat_TEI = Nat_TE($Nat_key);
// M.te
// this will fail
one : Int = Nat.one;
};
(x : Frozen key Nat) =>
unfreeze key
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
fix%Unit I unit = (
Unit = %unroll Unit I unit;
I = %unroll I unit;
unit = %unroll unit;
%self(u). (P : Unit -> Type) -> P unit -> I P u;
);
fix%unit I = (
unit = %unroll unit I;
Unit = %unroll Unit unit;
)
%self(u). (P : Unit -> Type) -> P (I unit) -> P (I u)
T_u : Type;
unit : T_u;
T_u = %self(u). (P : Unit -> Type) -> P (I unit) -> P (I u);
unit = P => (x : P (I unit)) => x;
fix%Unit C = (
Unit = %unroll Unit C;
C = %unroll C;
fix%unit C0 = (
unit = %unroll unit C0;
C0 = %unrol C0;
%fix(u) :
(P : Unit -> Type) -> P (C (C0 unit)) => x
.
(P : Unit -> Type) => (x : P (C (C0 unit))) => x
);
unit = %unroll unit _;
%self(u). (P : Unit -> Type) -> P (C unit) -> P (C u)
);
Unit : %self(Unit). (u : %self(u). %unroll Unit u) -> Type;
unit : %self(u). %unroll Unit u;
Unit u = (P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
!Unit = %fix(Unit). K => u => (
Unit = %self(u). %unroll Unit K u;
K = %unroll K u;
(P : Unit -> Type) -> P (K unit) -> P u
);
fix%UnitK unit = (
Unit = !Unit;
);
%unroll Unit C u ->
Unit : Type;
unit : Unit;
Unit = %self(u). (P : %unroll Unit -> Type) -> P unit -> P u;
unit = (P : %unroll Unit -> Type) => (x : P unit) => x;
!unit =
%fix(u): (P : Unit -> Type) -> P (C (%unroll unit C0)) -> P (C u).
(P : Unit -> Type) => (x : P (C (%unroll unit C0))) => %unroll C0 P x;
!T_C0 =
%self(C0). (P : Unit -> Type) -> P (C (%unroll unit C0)) -> P (C (!unit));
fix%Unit C = (
Unit = %unroll Unit C;
C = %unroll C;
fix%unit (C0 : !T_C0) = !unit;
C0 : !T_C0 = %fix(C0). P => P;
unit = ;
%self(u). (P : %unroll Unit C -> Type) ->
P (C (%unroll unit ?)) -> P (C u);
);
received :
%unroll I P (%fix(unit). P => (x : %unroll I P unit) => x) -> %unroll I P (%fix(unit). P => (x : %unroll I P unit) => x)
fix%unit I = (
(P : Unit -> Type) => (x : P unit) =>
)
Unit Unit C unit C0 = (
Unit = %unroll Unit C unit C0;
C = %unroll C unit C0;
unit = %unroll unit C0;
C0 = %unroll C0;
%self(u). (P : Unit -> Type) -> P unit -> C P u
);
unit Unit C unit C0 = (
Unit = %unroll Unit C unit C0;
C = %unroll C unit C0;
unit = %unroll unit C0;
C0 = %unroll C0;
%fix(u). (P : Unit -> Type) => (x : P unit) => C0 P x;
);
fix%Unit C unit C0 = (
;
);
fix%unit =
Unit : (u : %self(u). %unroll Unit u) -> Type;
unit : %unroll Unit unit
Unit u = (P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : (u : %self(u). %unroll Unit u) -> Type) => (x : P unit) => x;
Bool0 = {
self%Bool : (self%b : %unroll Bool b) -> Type;
self%true : %unroll Bool true;
self%false : %unroll Bool false;
Bool b = (P : (self%b : Bool b) -> Type) ->
P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
};
Bool = %self(b). %unroll Bool0.Bool b;
true : Bool = Bool0.true0;
false : Bool = Bool0.false0;
Mutual
(T_T : Type)
(M_T_T : (T : T_T) -> Type)
(T_C0 : (T : T_T) -> Type)
(M_T_C0 : (T : T_T) -> (C0 : T_C0 T) -> Type)
(E_T : %self(E_T).
(T : %self(T). (C0 : T_C0 T) -> M_T_T (%unroll E_T T C0)) ->
(C0 : T_C0 T) -> T_T)
(E_C0 : %self(E_C0). (T : T_T) ->
(C0 : %self(C0). M_T_C0 T (%unroll E_C0 T C0)) -> T_C0 T)
(M_T : (T : T_T) -> (C0 : T_C0 T) -> M_T_T T)
(M_C0 : (T : T_T) -> (C0 : T_C0 T) -> M_T_C0 T C0)
(T : T_T, C0 : T_C0 T) = (
fix%T (C0 : T_C0 T) : M_T_T (%unroll E_T T C0) = M_T (%unroll E_T T C0);
fix%C0 : M_T_C0 (%unroll E_C0 T C0) = M_C0 T (%unroll E_C0 T C0);
(%unroll E_T T C0, %unroll E_C0 T C0);
);
// from
Unit : (u : %self(u). %unroll Unit u) -> Type;
unit : %unroll Unit unit
Unit u = (P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : (u : %self(u). %unroll Unit u) -> Type) => (x : P unit) => x;
// to
(Unit, unit) = Mutual
// types
(%self(Unit). (u : %self(u). %unroll Unit u) -> Type)
(Unit => (u : %self(u). %unroll Unit u) -> Type)
(Unit => %self(unit). %unroll Unit unit)
(Unit => unit => %unroll Unit unit)
// equalities
(%fix(E_Unit). Unit => unit => Unit)
(%fix(E_unit). Unit => unit => unit)
// values
(Unit => unit => u =>
(P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u)
(Unit => unit =>
(P : (u : %self(u). %unroll Unit u) -> Type) => (x : P unit) => x);
// (fst : %self(fst). (s : %self(s). (K : Type) -> (A -> B (%unroll fst s) -> K) -> K) -> A)
fix%fst0 (A : Type) (B : A -> Type)
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K) =
%unroll s A ((x : A) => (y : B (%unroll fst0 A s)) => x);
Pair (A : Type) (B : A -> Type) =
%self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K;
pair (A : Type) (B : A -> Type) (x : A) (y : B x) : Pair0 A B =
%fix(s). (K : Type) => (k : A -> B x -> K) => k x y;
fst (A : Type) (B : A -> Type) (s : Pair A B) =
%unroll fst0 A s;
snd (A : Type) (B : A -> Type) (s : Pair A B) =
%unroll s (B (fst A B s)) ((x : A) => (y : B (fst A B s)) => y);
self%Unit : Type;
unit : Unit;
Unit = %self(u). (P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u;
unit = (P : (u : %self(u). %unroll Unit u) -> Type) => (x : P unit) => x;
!MUnit = %unroll MUnit MI;
!Unit = fst Type (Unit => Unit) !MUnit;
!unit = snd Type (Unit => Unit) !MUnit;
!Unit0 = %self(u). (P : !Unit -> Type) -> P (!unit) -> T P u;
!unit0 = %fix(u). (P : !Unit -> Type) => (x : P (!unit)) => C0 P x;
!T_T = %self(T). (P : !Unit -> Type) -> (u : !Unit0) -> Type;
!T_C0 = %self(C0). (P : !Unit -> Type) -> P (!unit) -> T P (!unit0);
!T_MI = Pair (!T_T) ((T : !T_T) => !T_C0);
!T_MUnit = %self(MUnit). (MI : !T_MI) -> Pair Type (Unit => Unit);
fix%MUnit (MI : !T_MI) =
pair Type (Unit => Unit) (!Unit0) (!unit0);
MI = %fix(MI).
Eq (A : Type) (x : A) (y : A) =
(P : A -> Type) -> P x -> P y;
Bool =
%self(k). (K : Type) ->
( -> K) -> K -> K;
case (b : ?) (K : Type) (x : ?) (y : ?) =
%unroll b K x y;
T =%self(eq). (K : Type) -> (x : _) -> (y : _) -> Eq _ (case b K x y) (x eq);
case b Int ((eq : ) => 0) (() => 1)
;
(Unit => unit => %unroll Unit unit)
(Unit => unit => u => (P : (u : %self(u). %unroll Unit u) -> Type) -> P unit -> P u)
(Unit => unit => (P : (u : %self(u). %unroll Unit u) -> Type) => (x : P unit) => x);
T_False : Type;
T_C : (False : T_False) -> Type;
T_False =
T_False =
%self(False).
(C : %self(C). (f : %self(f). (P : %unroll False C -> Type) -> P (%unroll C f)) -> %unroll False C)
-> Type;
T_C (False : T_False) =
%self(C). (f : %self(f). (P : %unroll False C -> Type) -> P (%unroll C f)) -> %unroll False C;
fix%False (C : %self(C). (f : %self(f). (P : %unroll False C -> Type) -> P (%unroll C f)) -> %unroll False C) =
%self(f). (P : %unroll False C -> Type) -> P (%unroll C f);
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
Bool = %frozen key Bool;
true : Bool = %freeze key true;
false : Bool = %freeze key false;
fix%fst0 (A : Type) (B : A -> Type)
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K) =
%unroll s A ((x : A) => (y : B (%unroll fst0 A s)) => x);
Pair (A : Type) (B : A -> Type) =
%self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K;
pair (A : Type) (B : A -> Type) (x : A) (y : B x) : Pair0 A B =
%fix(s). (K : Type) => (k : A -> B x -> K) => k x y;
fst (A : Type) (B : A -> Type) (s : Pair A B) =
%unroll fst0 A s;
snd (A : Type) (B : A -> Type) (s : Pair A B) =
%unroll s (B (fst A B s)) ((x : A) => (y : B (fst A B s)) => y);
%self(fst0).
(A : Type) -> (B : A -> Type) ->
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K) ->
A;
fix%fst0 (A : Type) (B : A -> Type)
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K) =
%unroll s A ((x : A) => (y : B (%unroll fst0 A s)) => x);
%self(fst0).
(A : Type) -> (B : A -> Type) ->
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A s) -> K) -> K) ->
A;
%self(False). (f : %self(f). %unroll False f) -> Type;
False : %self(x). _A;
// enter arrow
_A := (f : _C) -> _D;
// enter param
f : %self(f). _B
_C := %self(f). _B;
%unroll False : (f : %self(f). _B[x := False]) -> _D[x := False];
_B := %unroll False _E
%unroll False f : Type
%self(f). %unroll False _E[x := False] `unify` %self(f). %unroll False f
_D[x := False] `unify` %self(f). %unroll False f
_B := %self(f). %unroll False f;
// leave f
_A := %self(x).
%self. (%self. %unroll \1 \0) -> Type;
%self. (%self. %unroll (\1 : _A) (\0 : _B)) -> Type;
_A := %self. _C
%self. (%self. (%unroll \1 : _C) \0) -> Type;
_C[\1] `unify` (_D -> Type);
_B := _C[\1]
%self. (%self. %unroll \1 \0) -> Type
_B := %self. %unroll \1 \0;
%self(False0). (f : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
// enter arrow
_A := (f : _C) -> _D;
// enter %self(f0)
f0 : %self(f1). _E
_C := %self(f0). _F
%unroll False0 : (f : %self(f0). _F[False1 := False0]) -> _D[False1 := False0]
_A[False1 := False0] `unify`
(f : %self(f). %unroll False f) -> Type
%self(False0). (f : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
f0 : %self(f1). _B[f0 := f1]
%unroll False0 : _A[False0 := False1][False1 := False0]
_A[False0 := False1][False1 := False0] `unify` (f : _C) -> _D
_A :=
%unroll False0 f
%self(False0). (f : %self(f0). %unroll False0 f0) -> Type;
// enter self False
False0 : %self(False1). _A[False0 := False1]
// enter arrow
_A := (f : _B) -> _C
// enter self f
_B := %self(f0). _D
f0 : %self(f1). _D[f0 := f1]
// enter apply
_D := _F _G;
// enter unroll
_F := %unroll False0;
%unroll False0 : _A[False0 := False1][False1 := False0]
(f : %self(f0). %unroll False0 f0) -> _C[False0 := False1][False1 := False0]
// enter f0
_G := f0
_C[False0 := False1][False1 := False0] `unify` Type
expected
received : %self(f1). _E[f0 := f1]
expected : %self(f0). unroll False0 _F[False0 := False1][False1 := False0]
%self(False). (f : %self(f). %unroll False f) -> Type;
False : %self(False). _A
f : %self(f). _B
_A := %self(x).
%unroll False : _A
_A[x := y] === _A
call = f => x => (f : _A -> _B) x
id : (A : Type) -> A -> A;
x = call{Type, ?}(id, A);
%self(False0). (f : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
%unroll False0 : _A[False1 := False0]
_A := (f : %self(f0). %unroll False0 f0) -> Type
f : (x : _A) -> _B
f y : _B y
(f y : Int)
%self(False0). (f : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
f0 : %self(f1). _B[f0 := f1]
%unroll False0 : _A[False0 := False1][False1 := False0]
%unroll False0 : _A
_A := (f : _C) -> Type
_C := %self(f1). _B[f0 := f1];
%unroll False0 f0 : Type
// leave f0
(f : %self(f1). %unroll False0 f1) -> Type
`unify`
(f : %self(f0). %unroll False0 f0) -> Type
%self(False). (%self(f). %unroll False\1 f\0) -> Type;
// enter False
False : _A
// enter f
f : _B
(False\1 : _A[+1])
_A := %self(False). _C
%unroll False\1 : _C[+1]
_C := (_B[-1]) -> Type;
%unroll False\1 f\0 : Type;
_B := %self(f). %unroll False\2 f\0
// leave f
%self(False). (%self(f). %unroll False\1 f\0) -> Type `unify`
%self(False). (%self(f). %unroll False\1 f\0) -> Type
List : {
@List : (A : Type) -> Type;
map : {A, B} -> (f : A -> B, l : List A) -> List B;
} = _;
Mappable = {
@Container : Type;
map : {A, B} -> (f : A -> B, l : Container A) -> Container B;
};
map {M : Mappable} (x, f) = M.map(f, x);
User : (User : Type) & Map [
("id", User -> Nat)
("name", User -> String)
] = {
id : Nat;
name : String;
};
User = Record [
("id", Nat);
("name", String);
];
eduardo = Record.make User [
("id", 0);
("name", "Eduardo");
];
Map.get("id", eduardo)
User : {
id : User -> Nat;
name : User -> String;
};
user.id;
User.id(user)
l.map(x => )
l_ = List.map(f, l);
l.map(f);
map{List}(f, l);
l.map{List}(f);
x = List.map(f, l);
x = 1;
User : {
id : Nat;
name : String;
};
User = Record [
("id", Nat);
("name", String);
];
eduardo = User [
("id", 0);
("name", "Eduardo");
];
"id"
_Int\0 -> _Int\0
(A : Type) => A\0
(A : Type) => _A
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
f0 : %self(f1). _B[f0 := f1]
%unroll False0 : _A
_A := (f0 : _B) -> Type
%self(f1). _B[f0 := f1] `unify` %self(f0). %unroll False0 f0
_B[f0 := f1][f1 := f2] `unify` (%unroll False0 f0)[f0 := f2]
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0
%self(False0/1). (f0 : %self(f0/2). %unroll False0/1 f0/2) -> Type;
False0 : %self(False1/1). _A
f0 : %self(f1/2). _B
False0/1 : (%self(False1/1). _A)[+2]
%unroll False0/1 : _A[+1]
f0/2
_A := (f0 : (%self(f1/2). _B)[-1]) -> Type
(A : Type) -> 'A -> 'A
Int/+2 -> Int/+2
(A : Type) -> A/-1 -> A/-2
(A : Type) -> (A/+3 -> A/+3)[close 3]
(A : Type) -> (A/+3 -> A/+3)[close 3]
%self(False0/1). (f0 : %self(f0/2). %unroll False0/1 f0/2) -> Type;
False0/+1 : %self(False1). _A[False0/+1 := False1/-1]
f0/+2 : %self(f1). _B[f0/+2 := f1/-1]
%unroll False0/+1 : _A[False0/+1 := False1/-1][False1/-1 := False0/+1]
%self(False0/1). (f0 : %self(f0/2). %unroll False0/1 f0/2) -> Type;
False0/+1 : %self(False1). _A[close +1]
f0/+2 : %self(f1). _B[close +2]
%unroll False0/+1 : _A[close +1][open +1]
_A := (f0 : %self(f1). _B[close +2]) -> Type;
%unroll False0/+1 f0/+2 : Type
_B := %unroll False0/+1 f0/+2
%self(False0). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type;
False0 : %self(False1). _A[close +1]
f0 : %self(f1). _B[close +2]
_A := (f0 : %self(f1). _B[close +2]) -> Type;
%self(f1). _B[close +2] `unify` %self(f0). %unroll False0/-2 f0/-1
_B[close +2] `unify` %unroll False0/-2 f0/-1
_B `unify` %unroll False0/-2 f0/-1
_B := (%unroll False0/-2 f0/-1)[open +2]
_B := %unroll False0/-2 f0/+2
%self(False0). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type;
False0 : _A
f0 : _B
_A := %self(False1). _C
%unroll False0/+1 : _C
_C := (f0 : _B) -> Type
%unroll False0/+1 f0/+2
_B := %self(f0). %unroll False0/+1 f0/-1
%self(False1). %self(f0). %unroll False0/+1 f0/-1
%self(False0). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type;
False0 : _A
f0 : _B
_A := %self(False1). _C
%unroll False0/-2 : _C[False0/-2]
_C := (f0 : _B) -> Type
_B := %self(f0). %unroll False0/-2 f0/-1
%self(False1). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type
%self. (%self. %unroll /1 /0) -> Type;
/1 : _A
/
%self. (%self. %unroll /1 /0) -> Type;
/1 : _A[+1]
/0 : _B
_A := %self. _C[-1]
%unroll /1 : _C[/1]
_C := (f0 : _B) -> Type
_B := %self. %unroll /1 /0
%self. (f0 : %self. %unroll /1 /0) -> Type
A\
%self(False0). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type;
False0 : %self. _A
f0 : %self. _B
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type
False0 : %self(False1). _A
f0 : %self(f1). _B
%unroll False0 : _A[False1 := False0]
Option A =
(tag : Bool, tag | true => A | false => Unit);
Option A =
| (tag : "some", A)
| (tag : "none");
(f : Option Int) =>
switch (f) {
| ("some", x) => x + 1
| ("none") => 0
};
(f : Option Int) =>
match f
| ("some", x) => x + 1
| ("none") => 0;
(f : Option Int) =>
match f with
(("some", x) => x + 1)
(("none") => 0)
end;
(f : Option Int) =>
f
| ("some", x) => x + 1
| ("none") => 0
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
accepts_string_or_nat
: (pred : Bool) -> (x : pred Type String Nat) -> pred Type String Nat
= (pred : Bool) => (x : pred Type String Nat) => x;
accepts_string
: (x : String) -> String
= accepts_string_or_nat true;
Option A =
| (tag : true, payload : A)
| (tag : false);
OptionX A =
| (tag : false)
| (tag : true, payload : A);
Option A =
(tag : Bool, payload : tag | true => A | false => Unit);
((A : Type) => (x : A) => x) Int : Int -> Int
f : (A : Type) -> A -> A
Int : Type
f : (A : _A) -> _B
(A : Type)
(A/+2)[close +2 to -1] -> A/+2[close +2 to -2]
[], [] |- _A[close +2 to -1] `unify` _B[open -1 to +2]
[close +2 to -1], [open -1 to +2] |- _A `unify` _B
_A := _B
Int `unify` String
_A `unify` (A : Type) -> A -> A
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0/+2 : %self(False1). _A[close False0/+2]
f0/+3 : %self(f1). _B[close f0/+3]
%unroll False0/+2 : _A[close False0/+2][open False0/+2]
_A[close False0/+2][open False0/+2] `unify`
(f0 : %self(f1). _B[close f0/+3]) -> Type
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0 : %self(False1). _A[False0 := False1]
f0 : %self(f1). _B[f0 := f1]
%unroll False0 : _A
_A := (f0 : %self(f1). _B[f0 := f1]) -> Type;
%unroll False0 f0 : Type
_B := %unroll False0 f0
_A{x := y} `unify` _A{y := 1}
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0/2 : %self(False1). _A/2[False0/2 := False1/-1]
f0/3 : %self(f1). _B[f0/3 := f1/-1]
_C/4 := (x : _A/2) -> _B/3
(x : _A) -> _B[+2 `close` -1] `unify` (A : Type) -> A/-1 -> A/-2
_A := Type
_B[+2 `close` -1] `unify` A/-1 -> A/-2
_B{+2 `close` -1} `unify` A/-1 -> A/-2
_B := (A/-1 -> A/-2)[-1 `open` +2]
(x : _A) -> _B
(x : _A) -> _B `unify` (A : Type) -> A/-1 -> A/-2
_B[x := y] `unify` Int
_B := Int
_B y
_B := _ => Int
_B[A := Int] `unify` _B[A := String]
(x : _A) -> _B[-1 `open` +2] `unify` (A : Type) -> A/-1 -> A/-2
_B := A/-1 -> A/-2
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0/+2 : %self(False1). _A[/+2 `close` /-1]
f0/+3 : %self(f0). _B[/+3 `close` /-1]
%unroll False0/+2 : _A[/+2 `close` /-1][/-1 := False0/+2]
_A := (f0 : %self(f0). _B[/+3 `close` /-1]) -> Type
%unroll False0/+2 f0/+3
_B := %unroll False0/+2 f0/+3
%self(False1). (f0 : %self(f0). %unroll False0/-2 f0/-1) -> Type
#self[x => x]
@self[]
@deriving(show)
User = {
id : Nat;
};
@rec(User) = {
};
@self(x -> x)
@fix(x => x)
@unroll(M)
@unroll()
@unfold()
%fix(False). %self(f). (P : False -> Type) -> P f;
%self(False0). (f0 : %self(f0). %unroll False0 f0) -> Type;
False0/+2 : %self(False1). _A[/+2 `close` /-1]
f0/+3 : %self(f0). _B[/+3 `close` /-1]
%unroll False0/+2 : _A[/+2 `close` /-1][/-1 := False0/+2]
_A := (f0 : %self(f0). _B[/+3 `close` /-1]) -> Type
%unroll False0/+2 f0/+3
_B := %unroll False0/+2 f0/+3
Nat : {
@Nat : Type;
} = {
@Nat = Int;
};
Alias : Type = (x : Int) -> Int;
JSON : {
... : Type;
} = _;
Nat : {
T : Type;
} = {
T = Int;
};
(x : Nat) =>
JSON =
| Null
| Bool(b : Bool)
| Number(n : Float64)
| String(s : String)
| Object(d : List(String, @JSON))
| Array(l : List(@JSON));
JSON = JSON & {
};
User : (User : Type) & {
id : (user : User) -> Nat;
name : (user : User) -> String;
} = {
id : Nat;
name : String;
};
x = User.id(user);
(x : fst T).k === (snd T).k;
(x : T).k === T::k(x);
User : (User : Type) & fst {
id : Nat;
} = {
id : Nat;
name : String;
};
eduardo = { id = 0; name = "Eduardo"; };
x = eduardo::name;
User::id(user);
(x : T).k === T::k(x);
User : (User : Type) & {
id : (user : User) -> Nat;
name : (user : User) -> Nat;
} = (User = {
id : Nat;
name : String;
}) & {
id = (user : User) => user::id;
name = (user : User) => user::name;
};
Show = {
T : Type;
show : (x : S) -> String;
};
show{S : Show}(x : S.T) = S.show()
// User.tei
User = {
@User = {
id : Nat;
name : String;
};
impl@Show{self} = {
show () =
self.name ++ ": " ++ self.id.show();
};
};
User = {
... = extend({
id : Nat;
name : String;
});
}
... = include(Show);
(User = {
id : Nat;
name : String;
}) & {
show({self}) =
self.name ++ ": " ++ self.id.show();
};
User : (User : Type) & ((user : {
id : Nat;
name : String;
}) -> User) & {
}
eduardo = User {
id = 0;
name = "Eduardo";
};
print(eduardo.show());
(user : User).id === User::id(user);
(user : fst {
id : Nat;
}).id === snd {
id : Nat;
}.id(user)
(snd {
id : Nat;
} : fst {
id : (user : fst {
id : Nat;
}) -> Nat;
}).id === snd {
id : (user : fst {
id : Nat;
}) ->
}.id(User);
JSON : Type & {
} = {
... @JSON =
| Null
| Bool(b : Bool)
| Number(n : Float64)
| String(s : String)
| Object(d : List(String, @JSON))
| Array(l : List(@JSON));
};
@self(JSON, _). (
JSON : Type,
)
( == ) = (
( == ) = (P : ) &
( == ) =
)
f = x => x;
add = (a, b) => a + b;
f(1, 2)
deprecate : {A} ->
external : (key : String, A : Type) -[Const]> A;
hello = external("teika_c_hello", () -> String);
User = {
id : Nat;
name : String;
};
Row : {
type : (row : Row) -> Type;
} = _;
Record : {
Record = List(Row);
type : (record : Record) -> Type;
make : (rows : List(row : Row, value : Row.type row)) ->
Record.type(List.map(fst, rows));
keyof : (A : Type) -[Error]>
} = _;
keyof(User)
T_fst0 = %self(fst0).
(A : Type) -> (B : Type -> Type) ->
(s : %self(s). (K : Type) -> (A -> B (%unroll fst0 A B s) -> K) -> Type) -> A;
fst0 = %fix(fst0 : T_fst0).
A => B => s => %unroll s A (x => y => x);
Sigma (A : Type) (B : Type -> Type) =
%self(s). (K : Type) -> (A -> B (%unroll fst0 A B s) -> K) -> Type;
fst (A : Type) (B : Type -> Type) (s : Sigma A B) : A =
%unroll fst0 A B s;
snd (A : Type) (B : Type -> Type) (s : Sigma A B) : B (fst A B s) =
%unroll s (B (fst A B s)) (x => y => y);
// CPSify
// from
(snd e : B (fst e))
// to
{K} => (k : B (fst e) -> K) =>
e (y => snd y k)
T_fst0 = %self(fst0). {A} -> {B} ->
(s : %self(s). {K} -> (A -> B (%unroll fst0 s) -> K) -> K) ->
{K} -> (A -> K) -> K;
fst0 : T_fst0 = %fix(fst0). {A} => {B} =>
s => {K} => k => %unroll s (x => y => k x);
Sigma A B =
%self(s). {K} -> (A -> B (%unroll fst0 s) -> K) -> K;
fst {A} {B} (s : Sigma A B) =
%unroll fst0 s;
snd {A} {B} (s : Sigma A B) {K} (k : B (fst s) -> K) =
%unroll s K (x => y => k y);
E_T :
((x : {K} -> (Int -> K) -> K) -> x == 1)
(x = 1, eq : x == 1 = eq_refl)
(k : B (fst A B e)) => e ((s : Sigma A B) -> k (snd s))
// from
(e : Sigma A B)
// to
e : %fix(T). %self(e). {K : T -> Type} ->
(k : (y : Sigma A B) -> K (%fix(w). {K} => (k : (y : _) -> K w) => k y)) ->
K e
CPSifying Sigma seems to suffer from the same issue as lambda encoding of any inductive type, which is self reference.
The lambda encodings of inductive types can be solved by using self types, instead of declaring unit using the traditional church encoding, by using self types we self encode the induction principle, allowing to be known that (u : Unit) -> u == unit
.
// traditional church encoding of unit, no induction
Unit : Type;
unit : Unit;
Unit = (A : Type) -> (x : A) -> A;
unit = A => x => x;
// self dependent encoding of unit, inductive
Unit : Type;
unit : Unit;
Unit = %self(u). (P : Unit -> Type) -> P unit -> P u;
unit = P => x => x;
Instead of doing the traditional polymorphic CPS version, we can do a self referential CPS version
// original
x : A;
x = e;
// traditional CPS polymorphic
CPS : (A : Type) -> Type;
CPS = A => (K : Type) -> (k : (x : A) -> Type) -> K;
x : CPS A;
x = K => k => k e;
// self referential version
CPS : (A : Type) -> Type;
CPS = A => %self(x). (K : CPS A -> Type) ->
(k : (y : T) -> K (K => k => k y)) -> K x;
x : CPS A;
x = K => k => k e;
This allows to transform any external callback.
example : B (fst x)
example = x (a => B (fst a)) (y => snd y);
f(x) = x + 1;
f(2);
2 + 1
n = m
1 + n = 1 + m
n - 1 = m - 1
1 + x = 2
x = 2 - 1
(1 + x) - 1 = (2) - 1
x = 2 - 1
sort effects to achieve a set
extensions should be environment scoped, as in open should import extensions
@simpl, @cbn, @cbv, with a simple heuristics when the type is huge
expansion heuristics based on grading both for type level and term level
maybe type of dependent let should be a let
then, should type of a dependent apply be an apply?
() -> IO (Result String Error);
() -> Result (IO String) Error;
() -[IO | Error]> String;
() -[Error | IO]> String;
() -> Eff [IO, Error] String;
() -> Eff [Error, IO] String;
Eff effects ret = (
effects = Set.of_list(Effect => Effect.name, effects);
RawEff effects ret;
)
() -> Eff [IO, Error] String;
() -> Eff [Error, IO] String;
fold : (b : Bool) -> (A : Type) -> A -> A -> A;
// internalizing works
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
// internalizing fails, unbounded b, plus requires mutual recursion
Bool = (P : Bool -> Type) -> P true -> P false -> P b;
// with self the following can be done
Bool : Type;
true : Bool;
false : Bool;
Bool = %self(b). (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
(x : _A) -> _B `unify` (x : Int) -> P x\-0
(A : Type) => (x : A\-1) => (x : A\-2)
(x : A\+1) => (x : A\+1)
(x = 3; id (x + 1))
id (x + 1)
(A = Int; (1 : Int))
() -> Option(String);
IO(Option(String));
Option(IO(String));
Effect = (l, r) => (
l = sort(l);
Raw(l, r)
);
expected : () -> Eff([IO; Option], String);
received : () -> Eff([Option; IO], String);
read : () -[IO]> String;
f = () => read();
({
T = Int;
x : T = 1;
} :> {
x : Int
}) === {
x : Int = 1;
}
({
T = Int;
x : T = 1;
} :> {
x : Int
})
Int0 = _;
x0 : Int0;
Int = @frozen(((A : Type) => A) Int0);
x0 : Int = @freeze(x0);
Unit0 = _;
unit0 = _;
Unit = @frozen(Unit0);
unit = @freeze(unit0);
ind_unit = (u : Unit) => @unroll(@unfreeze(u));
Eq {A} x y : Type;
refl {A} x : Eq x x;
Eq {A} x y =
@self(eq ->
(P : (z : A) -> Eq x z -> Type) ->
P x (refl x) -> P y eq
);
refl {A} x = other => P => (x : P other x (refl x)) =>
other (refl x) (eq => _ => _ => P eq x (refl x)) x;
(x : Eq a b) => (p : P a) =>
x (refl a)
expected : P other x (refl x) -> P (refl x) x (refl x)
received : P other x (refl x) -> P (refl x) x (refl x)
uip : {A} -> (x : A) -> (eq : Eq x x) -> Eq eq (refl x)
= {A} => x => eq =>
eq (_ => eq0 => Eq eq0 (refl x)) (refl (refl x))
Eq (eq (z => _ => Eq z y) eq) (refl x)
f x = g x
f = g
f x = g x
f P f = g P g -> f = g;
!T_IT =
!T_unit = @self(unit -> @unroll Unit IT I0 unit);
!T_
T_Unit = @self(Unit ->
T_unit = @self(unit -> (IT : _) -> (I0 : _) -> @unroll Unit unit IT I0);
T_IT = (unit : T_unit) -> @self(IT -> (I0 : _) ->
(P : _) -> (u : @self(u -> (P : _) -> P (@unroll unit IT I0) -> @unroll IT I0 P u)) -> _)
(unit : @self(unit -> (IT : _) -> (I0 : _) -> @unroll Unit unit IT I0)) ->
(IT : @self(IT -> (I0 : _) ->
(P : _) -> (u : @self(u -> (P : _) ->
P (@unroll unit IT I0) -> @unroll IT I0 P u)) -> _)) ->
(I0 : @self(I0 ->
(P : _) -> P unit -> P (@fix((u : Unit) => (P : Unit -> Type) => (x : P unit) => I0 P x)))) ->
Type
);
Unit = @fix(Unit => unit => IT => I0 => (
Unit = @unroll Unit unit IT I0;
unit = @unroll unit IT I0;
IT = @unroll IT I0;
I0 = @unroll I0;
@self(u -> (P : Unit -> Type) -> P unit -> IT P u);
));
unit = @fix(unit => IT => I0 => (
Unit = @unroll Unit unit IT I0;
unit = @unroll unit IT I0;
IT = @unroll IT I0;
I0 = @unroll I0;
@fix((u : Unit) => (P : Unit -> Type) => (x : P unit) => I0 P x)
));
Unit = @unroll Unit;
Eq0 A x y = (P : A -> Type) -> P x -> P y;
Eq1 A x y
Nullable (A : Type) (not_nullable : Repr.not_nullable A) = A | null;
Nullable (Nullable A not_nullable) (?)
@mu(x -> )
add = (a, b) => a + b;
expr
| true => 1
| false => 2
Bool = | true | false;
add_and_mul = (a, b) => (
c = a + b;
a * c;
);
add_and_mul = (a, b) => (
c = a + (
d = b;
b + 1
);
a * c
);
no logical system can be complete and consistent
Naive set theory
does the set of all sets contains themselves?
forall x : Nat, (y : Nat, y > x)
1 = 0
(x => x + 1)(1)
1 + 1
2
f : (x : Nat) -> Fix Nat;
f : (x : Nat) -> Nat;
sort = selection_sort;
is_a_sort : bubble_sort == selection_sort = _;
f = l => first(sort(l));
f = subst(sort, f, bubble_sort);
fix = f => f(f);
Int = @frozen(((A : Type) => A) Int0);
x0 : Int = @freeze(x0);
Unit0 = _;
unit0 = _;
Unit = @frozen(Unit0);
unit = @freeze(unit0);
ind_unit = (u : Unit) => @unroll(@unfreeze(u));
Γ, f : @f(x : A) -> B, x : A |- B : Type
---------------------------------------
Γ |- @f(x : A) -> B : Type
Γ, f : @f(x : A) -> B, x : A |- M : B[x := @f(x : A) => M]
----------------------------------------------------------
Γ |- @f(x : A) => M : Type
Γ |- M : @f(x : A) -> B Γ |- N : A
-----------------------------------
Γ |- M N : B[f := M][x := N]
Id = @id(A : Type) -> (x : )
Rec () = Rec () -> Type;
(f(x : A) => M) N ===
M[f := f(x : A) => M][x := ]
Γ, f : @f(x : A) -> B, x : A |- B : Type
---------------------------------------
Γ |- @f(x : A) -> B : Type
False@0 : Type@0
T_False : Type@ω = @self(False@n -> (f : @self(f -> @unroll False@n f)) -> Type@n);
False : T_False = @fix(False@n => f =>
(P : @self(f -> @unroll False@n f) -> Type) => P f);
T_False (n : Level) : Type@(n + 1) =
@self(False@n -> (f : @self(f@n -> @unroll False@n f@n)) -> Type@n);
False : T_False =
@fix(False@1 => f => (P : @self(f@0 -> @unroll False@1 f@0) -> Type) -> P f);
@fix(Fix@1 -> @unroll Fix@1 -> ())
@fix(Fix@1 -> @unroll (@fix(Fix@0 -> @unroll Fix@0 -> ())) -> ())
Γ |- M : @self(x@n+1 -> T)
---------------------------------
Γ |- @unroll M : T[x := @upper M]
----------------------------------------------------------------
@unroll (@fix(x@n+1 => M)) === M[x := @upper (@fix(x@n+1 => M))]
@unroll (@fix(Fix@0 -> @unroll Fix@0 -> ())) -> ()
@unroll (@fix(Fix@1 -> @unroll Fix@1 -> ()))
@unroll (@fix(False@1 => @self(f@0 -> (P : @unroll False@1 -> Type@0) -> P f@0)))
T_False (l : Level) : Type (l + 2) =
@self(False@l -> (f : @self(f@l -> @unroll False f)) -> Type (l + 1))
False l : T_False l =
@fix(False@l => f => (P : @self(f@l -> @unroll False f) -> Type l) -> P f);
False l : Type (l + 1) = @self(f@l -> @unroll (False l) f);
@fix(False@1 => f => (P : @self(f@1 -> @unroll False f) -> Type 1) -> P f)
f : @self@1(f@l -> @unroll (False l) f)
@lower f : @self@0(f@l -> @unroll (False l) f)
@unroll f : (P : @self(f@0 -> @unroll False f) -> Type 0) -> P (@lower f)
@unroll f
False 0
@unroll (@fix(False@1 => f => (P : @self(f@0 -> @unroll False f) -> Type 0) -> P f));
f : @unroll False 1
f : (P : @unroll False 0 -> Type) -> P (@lower f);
f : @unroll (@fix(False@1 => @self(f@1 -> (P : @unroll False@1 -> Type@1) -> P f@1)))
f : @self(f@1 -> (P : @unroll (@fix(False@0 => @self(f@0 -> (P : @unroll False@0 -> Type@1) -> P f@0))) -> Type@1) -> P f@1)
@unroll f : (P : @self(f@0 -> (P : @unroll False@0 -> Type@1) -> P f@0) -> Type@1) -> P (@lower f)
@self(f@0 -> (P : @unroll False@1 -> Type@0) -> P f@0)
False@1 : @self(False@0 -> Type@0)
Fix : Type@2 = @unroll (@fix(Fix@1 -> @unroll Fix@1 -> ()))
fix : Fix = (f : @unroll (@fix(Fix@2 -> @unroll Fix@2 -> ()))) => f(f);
fix(fix)
@unroll False@1 : (f : @self(f@0 -> @unroll False@1 f@0)) -> Type@0
Γ |- M : @self(x@n+1 -> T)
--------------------------
Γ |- @unroll M : T[x := M]
@Unit () => @u(P : Unit () -> Type) -> P unit -> P u;
@fix(Unit). @self(u). (P : @unroll Unit -> Type) -> @expand P unit -> @expand P u
expected : @self(u). (P : @unroll Unit -> Type) -> P unit -> P u
received : @self(u). (P : @unroll Unit -> Type) -> P unit -> P u
(tag, payload : tag | true => String | false => Int)
tag | true => (payload : String)
ind (u : Unit) = @unroll u;
ind u
Γ |- A : Type
---------------------
Γ |- @frozen A : Type
Γ |- M : A
--------------------------
Γ |- @freeze M : @frozen A
Γ |- M : @frozen A
--------------------
Γ |- @unfreeze M : A
---------------------------
@unfreeze (@frozen M) === M
Car = interface(Car => {
speed : (self : Car) -> Speed;
top_speed : (self : Car) -> Speed;
speed_is_always_smaller_than_top_speed :
(self : Car) -> self.speed() < self.top_speed();
});
Bug = class(implements(Car), self => {
speed = 10;
top_speed = 120;
speed_is_always_smaller_than_top_speed = _;
});
Car = @fix(Car => @self(this -> {
speed : Speed;
top_speed : Speed;
speed_is_always_smaller_than_top_speed :
this.speed < this.top_speed;
}));
Bug : Car = @fix(this => {
speed = 10;
top_speed = 120;
speed_is_always_smaller_than_top_speed = _;
});
Electric_car = (top_speed, battery) => {
...Car(top_speed);
battery_size : () => baterry;
};
bug = Car(120);
bug.top_speed()
TEq : Type -> Type -> Type;
trefl : (A : Type) -> TEq A A;
TEq A B = @self(teq ->
(P : (C : Type) -> TEq A C -> Type) ->
P A (trefl A) -> P B teq;
);
trefl A = P => x => x;
HEq : {A, B} -> A -> B -> Type;
hrefl : {A} -> (x : A) -> HEq x x;
HEq {A, B} x y = @self(heq ->
(K : Type -> Type) ->
(P : (T : Type) -> (z : T) -> HEq x z -> K T) ->
P A x (hrefl x) -> P B y heq
);
hrefl {A} x = P => x => x;
uip_heq {A} (x : A) (heq : HEq x x) : HEq heq (hrefl x) =
heq (T => z => heq => HEq heq (hrefl x)) (hrefl x);
heq (T => a => HEq a 1) a
heq_to_eq {A} (x : A) (y : A) (heq : HEq x y) : Eq x y =
heq (T => z => _ => (x : T) -> Eq x z)
Eq : {A} -> A -> A -> Type;
refl : {A} -> (x : A) -> Eq x x;
Eq {A} x y = @self(eq ->
(P : (T : Type) -> T -> (z : A) -> Eq x z -> Type) ->
P (Eq x x) (refl x) x (refl x) -> P (Eq x y) eq y eq
);
refl {A} x = P => x => x;
uip_equal {A} (x : A) (eq : Eq x x) : Eq eq (refl x)
= @unroll eq (_ => _ => eq_e => Eq eq_e (refl x))
(@unroll eq
(z => eq => _ =>
Eq (@unroll eq _ (refl x)) (refl x))
(refl x))
Option (A : Type) =
| Some (payload : A) : Option A
| None : Option A;
Some : (A : Type) -> (payload : A) -> Option A;
None : (A : Type) -> Option A;
Ty (A : Type) =
| Ty_string : Ty String
| Ty_int : Ty Int;
One_or_zero (n : Nat) =
| Zero : One_or_zero 0
| One : One_or_zero 1;
f = (A : Type) => (ty : Ty A) => (x : A) : String =>
ty
| Ty_string => (x : String)
| Ty_int => Int.to_string(x : Int);
id
: (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
p : (x : Nat, x == 1)
fst p : Nat
snd p : (fst p) == 1
id = k => x => k x;
sum_3 = a => b => c => k => sum a b (a_b => sum a_b c k);
sum_3 = a => b => c => sum (sum a b) c;
Point : Type = sig
val "x" Int
val "y" Int
end;
zero_zero : Point = struct
let "x" 0
let "y" 0
end;
Point : Type = @sig({
x : Int;
y : Int;
});
Unit0 : @self(Unit0 -> _);
unit0 : @self(unit0 -> @unroll Unit0 unit0 _ _);
Unit1 = @unroll Unit0 unit0 _ _;
unit1 : Unit1 = unit0;
Unit = @frozen Unit1;
unit : Unit = @freeze unit1;
Unit : {
@Unit : Type;
unit : @Unit;
} = _;
Ind_type (T : Type) = (P : Type -> Type) -> P Type ->
((A : Type) -> (B : A -> Type) -> P ((x : A) -> B x)) -> P T;
Term (A : Type) =
Type : Type;
Type : @fix(Type => @self(T ->
(P : Type -> Type) -> P Type ->
P ((A : Type) -> (B : A -> Type) -> P ((x : A) -> B x)) -> P T
));
------
Type 0
---------------------
Type n : Type (n + 1)
Type : @fix(Type => @self(T -> (P : Type -> Type) -> P Type -> P T))
Type 1 : @self(T -> (P : Type 1 -> Type 1) -> P (Type 0) -> P T)
Type 1 : @unroll (Type 2) (X => )
----------------
Type 0 : Type 1
A : Type 0 B : Type 0
----------------------
(x : A)
Type 'n : Type ('n + 1);
(x : 'A : Type 'n) -> ('B x : Type 'n) : Type 'n;
(x : 'A) => (body : 'B x) : (x : 'A) -> 'B x;
(M : (x : 'A) -> 'B x) (N : 'A) : 'B N;
Type (n + 1) = @self(T -> (P : Type (n + 1) -> Type (n + 1)) ->
P ((A : Type n) -> (B : Type n) -> P ((x : A) -> B x)) -> P T);
((x : 'A) -> 'B x) = P => forall => forall A B;
((x : 'A) => body) = (arg : 'A) => body[x := arg];
(lambda arg) = lambda arg;
Ind_lambda A B f = (P : ((x : A) -> B x) -> Type) ->
((x : A) -> (r : B x) -> P ((x : A) => R x)) -> P f;
Map_W A B w = (x : A) -> (y : A) -> (Iso x y) -> W x -> W y;
eq : (x : A) -> f x = g x;
w : W ((x : A) => f x);
fn = ((x : A) => f x);
ind fn (f => W f)
(x => r => eq );
() -> IO (Option String);
() -> Option (IO String);
() -[Option | IO]> String;
Eff l = IEff (sort l) String;
() -> Eff [Option; IO] String;
() -> Eff [IO; Option] String;
List.map (x => external ("c_" ++ x)) ["hello"; "world"]
FFI = {
hello : String = "hello";
};
[external "c_hello"; external "c_world"]
ind
Nat64 : {
dup : (src : &Nat64, to_ : &mut Nat64) -> ();
// arith
add : (a : &Nat64, b : &Nat64, to_ : &mut Nat64) -> ();
sub : (a : &Nat64, b : &Nat64, to_ : &mut Nat64) -> ();
};
Mem : {
// better API
split : (mem : Mem, at : &Nat64) -[Invalid_offset]> (left : Mem, right : Mem);
merge : (left : Mem, right : Mem) -[Invalid_right]> (mem : Mem);
// TODO: is ptr needed?
load : (mem : &Mem, ptr : &Nat64, dst : &mut Nat64) -> ();
store : (mem : &mut Mem, ptr : &Nat64, src : &Nat64) -> ();
};
File : Type;
open : (
mem : &Mem,
path : &Nat64,
flags : &Nat64,
ret : Reg
) -> (file : File);
write : (
file : &mut File,
mem : &mut Mem,
buf : &Nat64,
len : &Nat64,
ret : Reg
) -> Nat64;
Table : Type;
load : (table : &mut Table, fd : Nat64) -> (file : File);
store : (table : &mut Table, file : File) -> (fd : Nat64);
F A = (G A, G A);
(x : Int) -> Eff([Fix], Int)
@fix((x) : Int => @unroll x);
type Ret<A> =
// TODO: unbox this, typeof or instanceof
| { tag : "jmp"; to_ : () => Ret<A>; }
| { tag : "ret"; value : A; };
type Fn<A, B> = (x : A) => Ret<B>;
function $call (f) {
const stack = [];
}
function $fix (f) {
return f(() => $fix(f));
};
$call
$jmp
$fix(x => y => x());
k => x => y => k y
true = x => y => x;
(x => y => x)(1)
(y => x)[x := 1]
(y => 1)
([], x => y => x)
true(1) -> ([1], x => y => x)
true(1)(2) -> ([1; 2], x => y => x)
true(1) -> (1, true)
true(1)(2) -> (1, 2, true) -> 1
received : _B/+2 -> (A : Type) -> A/-1
expected : _B/+2 -> (A : Type) -> _B/+2
A/+3 `unify` _B/+2
f = x => (y => y)(x);
g = x => x;
[],((λ (λ (λ ((#3 #2) s)))) (λ #1)) === [],((λ (λ (λ ((#3 #1) t)))) (λ #1))
[(λ #1)],(λ (λ ((#3 #2) s))) === [(λ #1)],(λ (λ ((#3 #1) t)))
[(λ #1),Abs],(λ ((#3 #2) s)) === [(λ #1),Abs],(λ ((#3 #1) t))
[(λ #1),Abs,Abs],((#3 #2) s) === [(λ #1),Abs,Abs],((#3 #1) t)
[(λ #1),Abs,Abs],(#2 s) === [(λ #1),Abs,Abs],(#1 t)
[Type],(A : Type) => (A/+1)[+1 := -1]
[Type],0,(B : Type) => (A : Type) => (A/+1)[+1 := -1]
[Type;B],0,(A : Type) => (A/+1)[+1 := -1]
[Type;B;A],0,(A/+1)[+1 := -1]
[Type;B;A;-1],+2,A/+1
[Type;-1],A/+1 -> A/-1
(A : Type) => A/-1
_B => _C
[Type; ]
[], (x => x)(y => y)(z)
[], (x => x)(y => y)
[x := y => y], x
[x := y => y], y => y
[], y => y
[], (y => y)(z)
[], y
(x => x)(y => y)(z)
(x[x := y => y])(z)
(y => y)(z)
(y[y := z])
z
T[x := y; y := z]
z
(x => x)(y => y)
(x => x(x))(z => z)
x(x)[x := z => z]
(x[x := z => z])(x[x := z => z])
(z => z)(z => z)
_A[x :=]
[z => z],\0(\0)
_A[x := y] `unify` y
_A `unify` y[y := x]
_A `unify` x
_A := x
x[x := y] `unify` y
[],_A[x := z] `unify` [],y[y := z]
[x := z],_A `unify` [y := z],y
_A := y[y := x][x := z]
_A := z
[Type],(A : Type) => (A/+1)[+1 := -1]
[Type],(B : Type) => (A : Type) => (A/+1)[+1 := /-1]
[Type;B],(A : Type) => (A/+1)[+1 := -1]
[Type;B;A],(A/+1)[+1 := -1]
[Type;B;A;-1],+2,A/+1
(A : Type) => (((B : Type) => B/+3[+3 := -1]) => A/+2)[+2 := -1]
(A : Type) => (((B : Type) => B/+1[+1 := -1]) => A/+2)[+2 := -1]
[]
fold : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
@Unit (@I : unit @-> _)
(@unit : (@C0 : _) -> @Unit I unit C0) (@C0 : _) : Type =
u @-> (P : @Unit I unit C0 -> Type) -> P (@unit C0) -> @I unit C0 P u;
@I unit C0 P x = x;
@unit C0 : @Unit I unit C0 = u @=> P => x => x;
@C0 P x = x;
expected : u
received : u @=> P => x => @C0 P x
@Unit
(@unit : u @-> (C0 : _) => @Unit unit C0 u) C0
(@u : @Unit unit C0 u) : Type =
(P : (@u : @Unit unit C0 u) -> Type) -> P (@unit C0) -> P u;
@unit C0 : @u -> @Unit unit C0 u =
u @=> P => x => @C0 P x;
@Unit (@I : _) : Type =
u @-> (P : @Unit I -> Type) ->
P (@I u) -> P (@I (u @=> P => x => x));
expected : P (@I (u @=> P => x => x))
received : P (@I u)
@Unit (@unit : _) (@C0 : _) (@u : @Unit u) : Type =
(P : (@u : @Unit unit C0 u) -> Type) ->
P u -> P (@unit C0);
T_unit = @Unit
@unit C0 : u @-> @Unit unit C0 u
= u @=> P => x => @C0
@Unit
(@I : _)
(@unit : (C0 : _) -> @Unit I unit C0)
(@C0 : _)
: Type =
u @-> (P : @Unit I unit C0 -> Type) ->
P (@I u) -> P (@unit C0);
I = _;
expected : @I P (u @=> P => (x : @I P u) => x)
received : @I P u
I : (u @-> (P : @Unit I -> Type) ->
@I P (u @=> P => x => x) -> @I P u)
@Unit (@I : _) : Type =
u @-> (P : @Unit I -> Type) ->
P (@I (u @=> P => x => x)) -> P (@I u);
@Unit (@I : _) : Type =
u @-> (P : @Unit I -> Type) ->
P (@I (u @=> P => x => x)) -> P (@I u);
(x : A) => x
(x : B) => x
@Bool (@I : _) : Type =
b @-> (P : @Bool I -> Type) ->
@I P (b @=> P => x => y => x) ->
@I P (b @=> P => x => y => y) ->
@I P b;
expected : P (@I (u @=> P => (x : P (@I u)) => x))
received : P (@I (u @=> P => (x : P (@I u)) => x))
@Unit
(@I : (u : _) -> @Unit I u)
(@u : @Unit I u)
: Type = (P : (@u : @Unit I u) -> Type) ->
P unit ->
P u;
expected : @I P (u @=> P => (x : @I P u) => x)
received : @I P u
Γ, x : x @-> T |- M : T
----------------------- // fix
Γ |- (@x : T) @=> M : T
|>
.
f . g
\x -> f (g x)
x => f(g(x))
add_incr = (x) => (
x = 1;
incr = y => x + y;
x = x + 3;
incr(1)
);
id = (x : _A) => (x : _A);
id = {A} => (x : A) => (x : A)
generic = var.level > 1e6
generic = var.level < level
id = (x : _A\1) => (x : _A\1);
id : (x : 'A\1) => (x : 'A\1)
id : (x : _B\0) => (x : _B\0)
y = id 1;
z = id "a";
id = (x : _A\1) => (x : _A\1);
id : (x : _B\0) -> _B\0
id 1
id "a"
id = (A : Type) => (x : A) => x;
x = id _ 1;
console.log{Int}(123);
@Unit (@I :
_
) : Type =
u @->
(P : @Unit I -> Type) ->
P (@I ((@u : ) @=> P => x => x)) ->
P (@I u);
expected : P (@I (u @=> P => x => x)) -> P (@I (u @=> P => x => x))
received : P (@I (u @=> P => x => x)) -> P (@I (u @=> P => x => x))
x => x : P (@I u) -> P (@I u)
Γ, x : x @-> T |- T : Type
-------------------------- // self
Γ |- x @-> T : Type
Γ, x : x @-> T |- M : T
----------------------------- // fix
Γ |- (@x : T) @=> M : x @-> T
x @=> (x : T)
x @-> T
Γ, x : x @-> T |- T : Type
-------------------------- // self
Γ |- x @-> T : Type
Γ, False : Self |-
Γ |- M : x @-> T
------------------- // unroll
Γ |- @M : T[x := M]
False @->
(f : f @-> @False f) -> Type;
(f0 : (A : Type) -> A) =>
(f1 : (P : False0 -> Type) -> P f0) =>
@x : (P : T -> Type) -> P x;
u @->
(P : Int -> Type) -> P (u P 1) -> Int;
Γ, x : x @-> T |- T : Type
-------------------------- // self
Γ |- x @-> T : Type
False @-> (f : f @-> @False f) -> Type;
False @-> (f : f @-> @False f) -> Type;
@self(False, f). (P : False -> Type) -> P f;
Unit I = _;
@self(Unit, u). (P : Unit -> Type) -> P unit -> P u;
(@Unit : Type) @-> Type;
(@Unit : Type) @-> () -> Type;
(@False : Type) @-> () -> Type;
(@Unit : Type) @=>
(P : Unit -> Type) -> P (@unit @=> P => x => x) -> P u;
Γ, x : T |- T : Type
-------------------------- // self
Γ |- @x @-> T : Type
(@False) @-> (f : @f @-> False (@f1 : False f1) @=> f);
f : False ((@f1 : False f1) @=> f)
(@f1 : False f1) @=> f
Γ, x : A |- B : Type
-------------------------- // self
Γ |- (@x : A) @-> B : Type
Γ, x : T |- M : T
----------------------------- // fix
Γ |- (@x : T) @=> M : x @-> T
(Unit : Type) @-> Type;
(@False : Type) @=> (f : False) @->
(P : False -> Type) -> P f;
(@Unit : Type) @=> (u : Unit) @->
(P : Unit -> Type) -> P (@unit @=> P => x => x) -> P u;
(@False : (f : (f : _) @-> False) @-> Type) @->
(f : (f : _) @-> False) @-> Type
(@False : ) @->
(f : (@f : False ((@f1 : False f1) @=> f)) @-> )
(@False : Type) @=> (f : _) =>
(P : ((@f : False f) @-> False f) -> Type) -> P f;
False @-> (f : f @-> False f) -> Type;
(@T_False : Type) @=>
(I : @((@IT : Type) @=> T_False ->
(I : IT) -> (False : T_False) @-> Type)) ->
(False : T_False) @-> Type;
(False : ?) @->
(I : @((@IT : Type) @=> False ==
(I : IT) f @-> (P : False I -> Type) -> I P f)) -> Type;
(@False : Type) @=> (f : _) @>
(P : ((@f : False f) @-> False f) -> Type) -> P f;
(@M : Type) @=>
(I : @((@IT : Type) @=> M == (I : IT) -> Type)) -> Type;
@False @=> I => f @-> (P : False I -> Type) -> I P f;
(A, False : A) @=>
_
(@False : (
@T_f : Type = (@f : T_f) @-> False f;
(f : ) -> Type
)) @=> (
@T_f : Type = (@f : T_f) @-> False f;
(f : (@f : T_f) @-> False f) -> Type
);
(@M : Type) @=>
(I : @((@IT : Type) @=> M == (I : IT) -> Type)) -> Type;
(@M : Type) @=>
(I : @((@IT : Type) @=> M == (I : IT) -> Type)) ->
(x : M) @->
(eq : @((@eqT : Type) @=>
(eq : eqT) -> I _ x I eq == 1)) ->
Int;
@T_False : Type =
(False : T_False) @->
(I : @((@IT : Type) @=> False == )) -> Type;
(False : T_False) @=> I =>
(f : @False I) @-> (P : @False I -> Type) -> I _ P f;
@T_I (M : Type) : Type = M == (I : T_I M) -> Type;
@M : Type = (I : T_I M) -> Type;
@T_I (T_False : Type) : Type =
T_False == _;
@T_False : Type =
(I0 : T_I0 T_False) ->
(False : T_False) @->
(I1 : T_I1 T_False False) ->
(f : f @-> @I1 False I1 f)
Type;
(@False : T_False)
@False : T_False = I => (
f @-> (P : False I -> Type) -> P f
);
@Unit (
@I : (
u @-> (P : Unit I -> Type) -> P (I (u @=> P => x => x)) -> P (I u)
) -> Unit I
) = u @-> (P : Unit I -> Type) -> P (I (u @=> P => x => x)) -> P (I u);
Unit = Unit (@I @=> x => x);
unit : Unit = u @=> P => x => x;
@Unit I =
u @-> (P : Unit I -> Type) -> P (I (u @=> P => x => x)) -> P (I u);
read : (world : World, file : String) -> (world : World, content : String);
print : (world : World, message : String) -> World;
main : World -> World;
read : (world : &mut World, file : String) -> String;
print : (world : &mut World, message : String) -> ();
main world = (
(world, hello) = read(world, "hello.txt");
world = print(hello);
(world, bronha) = read(world, "bronha.txt");
print(world, bronha);
);
main world = (
hello = read(world, "hello.txt");
() = print(hello);
bronha = read(world, "bronha.txt");
print(bronha);
);
IO X : World -> (World, content : X)
main () = (
hello = read(world, "hello.txt");
() = print(hello);
bronha = read(world, "bronha.txt");
() = print(bronha);
()
);
main : IO ();
Γ |- A : Type Γ |- n : Grade
-----------------------------
Γ |- M : A $ n
Γ, x : A $ n |- B : Type $ 0
------------------------------------
Γ |- ((x : A $ n) -> B $ m) : Type $ 0
Γ, x : A $ n |- M : B $ m
--------------------------------------------------
Γ |- (x : A $ n) => M : ((x : A $ n) -> B $ m) $ k
Γ |- M : ((x : A $ m) -> B $ n) $ 1 Γ |- N : $ n
--------------------------------------------------
Γ |- M N : ((x : A $ n) -> B $ m) $ k
f = x => x + x;
f = (x : Int) => x + x;
Γ |- M : A
Γ |- M : A $ n
f : (!x : Nat, !y : Nat, ?z : Nat = 1) -> Nat;
f (1, 2, 3);
1 ^ 1
(+) : (x : Nat, y : Nat) -> Nat &
(+) : (x : String, y : String) -> String;
S S S Z + S S Z = S S S S S Z
"abc" + "de" = "abcde"
(+) : (x : Nat, y : Nat) -> Nat &
(+) : (x : String, y : String) -> String;
(+) : ()
Linear HM == Mono Unification
Linear System F == Mono Unification
Multiplicative System F == Mono Unification + Intersection
(id : _A & _B $ 2) => ((id : _A) 1, (id : _B) "a")
(id : Int -> _A & String -> _B $ 2) => ((id : _A) 1, (id : _B) "a")
Nat<G> = (A : Type) -> (z : A $ 1) ->
(s : (G : Grade) -> (A -> A) $ G) -> A;
(G : Grade) => (x $ G) => _;
(id : _A & _B $ 2) => (id 1, id "a")
Γ |- A : Type
-------------
Γ |- M : A
Γ |- A : Type $ 0 Γ |- G : Grade $ 0
-------------------------------------
Γ |- M : A $ G
Γ, x : A |- B : Type
------------------------
Γ |- (x : A) -> B : Type
(A : Type $ 1) => (x : A) => (
(A) = A;
x
);
(A : Type) => (x : A) => x;
Bool = (A : Type) -> A -> A -> (A, Garbage);
Bool = (A : Type) -> A -> A -> Weak A;
A ->
(A : Type $ 2) => (x : A) => ((x : A) => x) x;
((x : A) => M) N ==
() <- weak A;
M[x := N]
Γ |- M : (x : A) -> B ! Δ1 Γ |- N : A ! Δ2
-------------------------------------------
Γ |- M N : B[x := N] ! Δ1, Δ2, Weak
(x : Nat $ 2) => x + x;
(x0 : Nat) => (x1 : Nat) => (eq : x0 == x1) => x0 + x1;
id
: (A : Type $ 2) -> (x : A) -> A;
= (A : Type $ 2) => (x : A) => x;
(A : Type) -> (B : Type) ->
(eq : (P : Type -> Type) -> P A -> P B) ->
(x : A) -> B
Pair (A : Type) (B : Type) =
(K : Type) -> (k : ((x : A) -> (y : B) -> K)) -> K;
Unit = (A : Type) -> ()
Exist = ((A : Type) -> (x : A) -> Unit) -> Unit
Weak (A : Type) =
(G : Type, x : Exist)
(A : Type $ 2) => (x : A) => ((x : A) => x) x;
(A : Type $ 2) => (x : A) => (() = weak A; x);
(s : Socket $ 2) => (
)
add : (n : Nat) -> (m : Nat) -> Nat
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
ind : (b : Bool (n + 1)) ->
(P : Bool n -> Type) -> P true -> P false -> P (lower b);
(x : Nat) -> (y : Nat) -> x *
(x : A $ 1) -> B ! Δ $ n
(x : A $ 2) -> B $ 2
(x : A $ 1) -(2)> B
(x : A $ 1) -[IO $ 2]> B
(x : A $ 1) -()> B
Γ |- M : P
(x : Int $ 2) => x + x;
Ref : {
@Ref (A : Type) : Type$;
make : {A} -> (value : A) -> Ref A;
get : {A} -> (cell : Ref A) -> (cell : Ref A, value : A);
set : {A} -> (cell : Ref A, value : A) -> (cell : Ref A);
} = _;
x = cell = (
cell = Ref.set(cell, 1);
(cell, value) = Ref.get(cell);
cell
);
main : World$ -> World$;
read : (world : World$, file : String) -> (world : World$, content : String);
print : (world : World$, message : String) -> World$;
main : IO ()
main world = (
(world, hello) = read(world, "hello.txt");
world = print(world, hello);
(world, bronha) = read(world, "bronha.txt");
print(world, bronha);
);
map : {A B} -> (l : List A, f : (el : A) -> B) -> B;
map : {A B} -> (l : List {G} A $ 1, f : ((el : A $ 1) -> B $ 1) $ G) -> B $ 1;
map : {A B G} -> (l : List G A $ 1, f : ((el : A $ 1) -> B $ 1) $ G) -> B $ 1;
add : (l : List 1 A, a : Nat $ 1) = (l, a) =>
map(l, (el => el + a) $ 1);
f = (a : Nat $ 0) => 1;
List L A = {K} -> (initial : K $ 1, fold : (acc : K, el : A) -> K $ L) -> K;
Type : Type
id : A. A -> A = x => x;
id : (A : Type) -> A -> A =
(A : Type) => x => x;
forall A. A -> A
forall A -> A -> A
id : forall A. A -> A = A => (x : A) => x;
id : {A} -> (x : A) -> A;
id {A} x = x;
id : ?A -> (x : A) -> A;
id ?A x = x;
User : (User : Type & {
make : (name : String) -> User;
}) = _;
User : Type & {
make : (name : String) -> User;
} = _;
User : {
@User : Type;
make : (name : String) -> @User;
} = _;
id = (!x : Nat) => x;
x = id(x = 1);
f = (x : User) => x;
add (1, 2)
?add (1, _)
add 1 2
?add 1 _
pair _A 1 _A 2
<A> (x : A) -> A
<A> (x : A) => x;
<A> -> (x : A) -> A
<A> => (x : A) => A
id <A>
{A} (x : A) -> A;
{A} (x : A) => x;
{A} -> (x : A) -> A;
{A} => (x : A) => x;
id {A}
[A] (x : A) -> A;
[A] (x : A) => A;
[A] -> (x : A) -> A;
[A] => (x : A) => x;
id [A]
(?A) -> (x : A) -> A;
(?A) => (x : A) => x;
id ?A
-(IO)>
-[IO]>
`
~
id <A> x = x;
(<A : Int>, x : Int)
pair : <A>(x : A, y : A) -> Pair A B;
(==) : <A>(x : A, y : A) -> Bool;
(==) : <A>(x : A, y : A) -> Type &
(==) : <A : Eq>(x : A, y : A) -> Option (x == y);
x => y => (x == y : _A where _A == Type or _A == Option (x == y))
id (A : Type) (x : A) = x;
%macro (A : Type $ 1) =
x => %printf (x : _A)
x => _B x
when _A to Int == _B := Int.printf
x => Int.printf x
extract "/users/:id" : ("id", _ : _A)
"a" : Type | String
((x : "a") => _) ("a")
Either(A, B) =
| ("left", A)
| ("right", B);
Either(A, B) =
| Left(A)
| Right(B);
Either(A, B) =
| (tag : "left", A)
| (tag : "right", B);
x
| ("left", x) => _
| ("right", y) => _
(>) : <A>(x : A, y : A) -> Type &
(>) : <A : Cmp>(x : A, y : A) -> Option (x > y);
1 == 2 : Option (1 == 2)
(==) : <A>(x : A, y : A) -> Type
f = (x : 1 == 1) => x;
Eq A = {
eq : (x : A, y : A) -> (x == y | x != y);
}
x => y => eq x y
f (eq x 1 | Some eq => eq);
pair <Int> (1, 2)
[%mode dynamic]
f = x => x;
x : Dyn = 1;
Int.add : (x : Int, y : Int) -> Int
Int.add (assert.Int x) : 1 ! Assert $ n
| "int" => (x : Int)
useless : (<A : Type>, x : A) -> (A : Type, x : A)
useless(1)
id ~x = 1
\(A)/ ->
id::[1]
id : <A>(x : A) -> A;
id <A> x = x;
id <A> x = x;
id ?Int 1;
{ x; y; } = { x = 1; y = 2; };
Id : Type = (A : Type) => A;
f (x : Int & x > 0) = (
1
);
@id {Int} 1 = 1
id : forall a. a -> a
id (x : a) = x
f (id : Int -> 'A & String -> 'B $ 2) = (id 1, id "a")
f {G} l = _
f {1} [1] = _
add = a =>
map(l, el => el + a);
map : {A B} -> (l : List A, f : ({G} -> ((el : A) -> B) $ G) $ 1) -> B;
map : {A B} -> (l : List A, f : (el : A) -> B) -> B;
id = (A : Type $ 0) => (x : A $ G) => x;
double = (x : Nat $ 2) => x + x;
id = (A : Type) =>
Fix = (x $ 2 : Fix) -> ();
((x $ 4 : Fix) => x x);
case : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = (P : Bool -> Type) -> P true -> P false -> P b;
Bool : Type
true : Bool
false : Bool
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
true = (P : Bool -> Type) => (x : P true) => (y : P false) => x;
(x : $Socket)
(x $ 4 : Nat) =(2)> (x + x)
() -> @fix(S). S
T =
@fix(S). (f : (A : Nat) -> Type $ 0) -> f 1;
Type : Type
(G : Grade) => (x $ G) =>
Γ | Δ, x : A |- M : B
------------------------------------
Γ | Δ |- (x : A) => M : (x : A) -> B
(A : Socket $ 2) =>
(A $ n) $ m
Socket = _ $ 1;
(x : Socket $ 2) => x;
Array : {
Write : {
@Write (A : Type) : Type;
};
Read : {
@Read (A : Type) (x : Write A) : Type;
split : <A>(x : Write A) -> (l : Read A x, r : Read A x);
merge : <A>(x : Write A $ 0, l : Read A x, r : Read A x) -> (x : Write A);
};
};
Γ |- A : Type Γ |- n : Grade
------------------------------
Γ |- A $ n : Type
Γ |- M : A M == N
------------------
Γ |- M + N : A $ 2
---------------
Γ |- A $ 1 == A
(x : _A $ _G) => x;
(x : _A $ _G) => x + x;
1 :: id ::
t :: id |- \0 -> t
x[open := t]
_A[open x/+2] `unify` x\+2
_A := x/+2[close +2]
_A := x/-1
x/+2[close +2][open x/+2]
x/+2[+2 := -1][-1 := x/+2]
(_ => x/-2)[open x/+2]
x/-2[Lift][open x/+2]
[open x/+2; id] |- _A `unify` [Free; Free]
A/-1 -> A/-2
(A/+2 -> A/+2)[close +2]
A/+2[close +2] ~~> A/-1
A/+2[id][close +2] ~~> A/-2
A => B => _C `unify` A => B => A/+2[id][close +2]
{} [id; id;] |- _C `unify` [id; id; close +2; id;] |- A/+2
A => (B => A/+2)[close +2]
A => B => A/+2[id]
_C := A/+2[id][close +2][id][id][-id][-id]
{} - [id;] |- A/+2[id][close +2]
{ +2 = 0; } - [id;] |- A/+2[id]
{ +2 = 0; } - [id; id;] |- A/+2 ~~> A/-2
A => A/-1
A => A/+2[close +2]
{} - [] |- A/+2[close +2]
{ +2 = 0; } - [] |- A/+2 ~~> A/0
{ +2 = 0; } - [id] |- A/+2
A/-2[id][open x/+2] ~~> A/+2
A/+2[close +2][open +2] ~~> A/+2
A/+2[id][close +2] ~~> A/-2
A/+2[id][close +2][id][open +2] ~~> A/+2
A/+2 ~~> A/-2 ~~> A/
[Free, Free] |- A/+1
x @
| a
| b
Free = +
Bound = -
+A
A => -A
λ.λ.\1
(λ.λ.\1) "a" "b"
"b" :: "a" :: [] |- \1 ~> "a"
codemod that tags every occurencce of identifier so that the dev needs to go and check the code, removing the annotation
Type\1
String\2
A\3
Sorry\2
@fix(False). (f : @self(f -> @unroll False f)) =>
(P : (f : @self(f -> @unroll False f)) -> Type) -> P f
False : @self. _A[close +3]
f : @self. _B[close +4]
@unroll \+3 : _A
_A := (f : @self. _B[close +4]) -> Type
@unroll \+3 \+4 : Type
_B := @unroll \+3 \+4
False : @self. (f : @self. @unroll \-1 \-0) -> Type
f : @self. _C[close +5]
@unroll \+3 : (f : @self. @unroll \+3 \-0) -> Type
@unroll \+3 \+5 : Type
expected : @self. @unroll \+3 \-0
received : @self. _C[close +5]
@self. @unroll \+3 \-0 `unify` @self. _C[close +5]
@self. @unroll \+3 \-0 `unify` @self. _C[close +5]
(False : @self. (f : @self. @unroll False f) -> Type) =>
(P : (f : @self(f -> @unroll False f)) -> Type) -> P f
(False : @self(False -> (f : @self. @unroll False f) -> Type)) =>
(P : (f : @self(f -> @unroll False f)) -> Type) -> P f
False : @self. (f : @self. @unroll \-1 \-0) -> Type
f : _A
@unroll \+3 : (f : @self. @unroll \+3 \-0) -> Type
@unroll \+3 \+5 : Type
@self(False). (f : @self(f). @unroll False f) -> Type
False : @self. _A[close +3]
f : @self. _B[close +4]
@unroll \+3 : _A
_A := (f : @self. _B[close +4]) -> Type
@unroll \+3 \+4 : Type
_B := @self. @unroll \+3 \-0
@self. (f : @self. @unroll \+3 \-0) -> Type[close +4]
False : @self. (f : @self. @unroll \-1 \-0) -> Type
f : @self. _B
@self((f : @self(f -> _B)) -> @unroll \+3 \-0)
f : @self. _A[close +5]
@unroll \+3 : (f : @self. @unroll \+3 \-0) -> Type
@unroll \+3 \+5 : Type
@self. @unroll \+3 \-0 `unify` @self. _A[close +5]
(@unroll \+3 \-0)[open \+6] `unify` (_A)[close +5][open \+6]
(@unroll \+3 \-0) `unify` (_A)[close +5]
(@unroll \+3 \-0) `unify` (_A)[open \+5]
@self(False -> (f : @self. @unroll False f) -> Type)
False : _A
f : _B
@unroll \+3
@self. _C[close +3] `unify` @self. _A
False : _A
(False : @self(False -> (f : @self. @unroll False f) -> Type)) =>
(P : (f : @self(f -> @unroll False f)) -> Type) -> P f
False : @self. (f : @self. @unroll \-1 \-0) -> Type)
f : @self. _B[close +5]
T[subst] === U[subst]
T === U
_ -> _A -> _A === _ -> \-0 -> \-1
(_A -> _A)[subst] === (\-0 -> \-1)[subst]
_A\+3 -> _A\+3 === \-0 -> \-1
_A\+3 := \-0
( + ) : Int -> Int -> Int;
x => x + 1
Γ, x : _A |- x + 1 : Int
_A := Int
incr : Int -> Int = x => x + 1;
map(x => x + 1)
(x : Int) => x + 1
(x => x) : 'a. 'a -> 'a
Γ, x : _A |- x : _A
id
: (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
id(String) : ((x : A) -> A)[A := String]
f = (id : (A : Type) -> A -> A) => (id(1), id("a"))
3 [] {} |- \+3[close +3][open \+3]
4 [\+3 - 4] {} |- \+3[close +3]
5 [\+3 - 4] { +3 := -0 - 5 } |- \+3 ~> \-0
4 [\+3 - 4] { +3 := -0 - 5 } |- \+3 ~> \-0 ~> \+3
\+3[close +3][open \+3]
\+3[close +3][open \+3]
5 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-0
4 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-0 ~> \+3
3 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-0 ~> \+3 ~> \-0
\+3[close +3][open \+3]
\-1[open \+3][close +3][open \+3]
Γ, open \+3, close +3, open \+3, close +4 |- \-0
Γ, open \+3, close +3, open \+3 |- \-0
Γ, open \+3, close +3 |- \+3
Γ, open \+3 |- \-0
Γ |- \+3
[] |- \+3[close +3]
[Type] |- (A : Type) -> ((x : A\+2) -> A\+2)[close]
[Type] |- (A : Type) -> ((x : A\+2) -> A\+2)[close]
\+3[close +3][open \+3]
expected : (A : Type) -> A -> A
received : (B : Type) -> B -> B
expected : (A : Type) -> \-1 -> \-2
received : (B : Type) -> \-1 -> \-2
(A : Type\+0) -> \+1 -> \+1
(A : Type) => (x : \-1 -> \-2) => (x : \-2 -> \-3)
(A : Type\+0) -> \-1
(A : Type) -> (\+1 -> \+1)[close]
(A : Type\+0) -> \-1 -> \-2
(B : Type\+0) -> _A -> _A
A := \-1
(A : Type\+0) -> \-1 -> \-2
(B : Type\+0) -> \-1 -> \-1
(\-1 -> \-2)[open +4]
\+4 -> \+4
_A -> _A
\+3[close +3][open \+3]
close +3 open \+3 |- \+3
\+3[close +3][open \+3]
[\+3] { +3 := -0 } |- \-0 ~> \+3 ~> -0
(\+3 -> \+3)[close +3][open \+3]
\+3 -> \+3[close +3][open \+3]
@self. @unroll \+3 \-0 `unify` @self. _A[close +5]
(@unroll \+3 \-0)[open \+6] `unify` _A[close +5][open \+6]
(@unroll \+3 \-0) `unify` _A[close +5]
(@unroll \+3 \-0)[open \+5] `unify` _A
|- @self. @unroll \+3 \-0 `unify`
|- @self. _A[close +5]
[] |- @self. @unroll \+3 \-0
[close +5; ] |- @self. _A
[open \+6; ] |- @unroll \+3 \-0
[close +5; open \+6; ] |- _A
_A := @unroll \+3 \-0[open \+5]
x = 1;
eq : x + 1 == 2 = refl;
x == 1;
f : (A : Type) -> (\+1 -> \+1)[close ] = _;
f
[Type] |- (A : Type) -> ((x : A\+1) -> A\+1)[close]
\+3[open \+3][close +3]
[] {} |- \+3[open \+3][close +3]
[] { +3 := -1 } |- \+3[open \+3]
{} |- \+3[close +3][open \+3]
{} |- \+3[\+3 := \-1][\-1 := \+3]
{ \-1 := \+3; } |- \+3[\+3 := \-1]
{ \-1 := \+3; \+3 := \-1; } |- \+3
{ \-1 := \+3; } |- \-1
{ } |- \+3
{} |- \+3[close +3][open \+3]
{} |- \+3[\+3 := \-1][\-1 := \+3]
{ \-1 := \+3; } |- \+3[\+3 := \-1]
{ \-1 := \+3; \+3 := \-1; } |- \+3
{ \-1 := \+3; \+3 := \+3; } |- \+3
{} |- \+3[close +3][open \+3 -> \+3]
{} |- \+3[\+3 := \-1][\-1 := \+3 -> \+3]
{ \-1 := \+3 -> \+3; } |- \+3[\+3 := \-1]
{ \-1 := \+3 -> \+3; \+3 := \-1; } |- \+3
{ \-1 := \+3 -> \+3; \+3 := \+3 -> \+3; } |- \+3
{} |- \+3[\+3 := \+3 -> \+3][\-1 := \+3 -> \+3]
{} |- \+3[\+3 := \-1][\-1 := \+3 -> \+3]
\+3[\+3 := \+3][\-1 := \+3]
\-1[open \+3][close +3][open \+3]
5 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-1
4 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-1 ~> \+3
3 [\+3 - 4] { +3 := [\-0 - 3; -0 - 5] } |- \-1 ~> \+3 ~> \-1
+1 |- (A : Type) -> \+1 -> \+1
+4 |- (A : Type) -> \+4 -> \+4
(A : Type) -> (\+1 -> \+1)[close +3]
(\-1 -> \-2)[open +3]
f : (Int\-1 -> Int\-2)[open Int\+3]
x : Int\-2[id][open Int\+3]
expected : Int\-1[open Int\+3]
received : Int\-1[id][open Int\+3]
2 [] |- (A : Type) -> A\-1 -> A\-2
2 [] |- (A : Type) -> _B -> _B
2 [] |- (A : Type) -> A\-1 -> A\-2
2 [] |- (A : Type) -> _B\+3 -> _B\+3
3 [open A\3; ] |- A\-1 -> A\-2
3 [open A\3; ] |- _B\+3 -> _B\+3
_B := A\-1
3 [A\3;] |- A\-1 -> A\-2
3 [A\3; A\3;] |- _B -> _B
3 [A\3;] |- A\-1
3 [A\3; A\3;] |- _B
_B := A\-1[close ]
2 [] |- (A : Type) -> _B[close] -> _B[shift][close]
3 [] |- (A\-1 -> A\-2)[open A\+3]
3 [] |- (_B[close] -> _B[shift][close])[open A\+3]
3 [open A\+3] |- A\-1 -> A\-2
3 [open A\+3] |- _B[close] -> _B[shift][close]
3 [open A\+3] |- A\-1
3 [open A\+3] |- _B[close]
3 [open A\+3] |- A\-1
3 [open A\+3; close] |- _B[]
3 [] |- (A\-1 -> A\-2)[open A\+3]
3 [] |- (_B -> _B)[close][open A\+3]
[] |- (A\-1 -> A\-2)[open A\+3]
[] |- (_B -> _B)[open A\+3]
[A\+3] |- A\-1 -> A\-2
[A\+3] |- _B -> _B
_B := A\-1[A\+3]![A\+3]
x => id(x)
x => x
[Int : Type] |- (x : Int\1 = _; x\1 : (Int\1)[lift])
[Int : Type; x : Int\1] |- (x\1 : (Int\2)[lift])
[] |- x\-1[y\-2][id][x\-1]
[x\-1] |- x\-1[y\-2][id]
[x\-1; id] |- x\-1[y\-2]
[x\-1; id; y\-2] |- x\-1
[x\-1; id] |- y\-2
[x\-1] |- y\-1
[] |- x\-1
1[2 . id][2 . id]
2[2 . id]
1
[] |- 1[2 . id][2 . id]
[2 . id] |- 1[2 . id]
[2 . id; 2 . id] |- 1
[2 . id] |- 2
[] |- 1
1[2[shift] . id]
2[shift]
3
[] |- 1[2[shift] . id]
[] |- 1[2 . id][1 . id]
[] |- 1[2[shift] . id]
[2[shift] . id] |- 1 ~> 2[shift]
[2[shift] . id] |- 2[shift]
[2[shift] . id] |- 2[2 . id]
[] |- 2[3 . id]
[2 . id] |- 2
[] |- -1[open +3]
\+3[close +3][open \+3]
4 [] {} |- \+3[close +3][open \+3]
5 [] { +4 : 4 } |- \+3[close +3]
4 [] |- \+3[close +3][open \+3]
4 [open \+3] |- \+3[close +3]
4 [close +3; open \+3] |- \+3
4 [open \+3] |- \-1
4 [] |- \+3
[] [] |- \+1[close +1][open \+1]
[open \+1] [] |- \+1[close +1]
[open \+1] [close +1 at 1] |- \+1
[open \+1] [] |- \-1
[] [] |- \+1
[] [] |- \+1[close +1][shift]
((A : Type) -> \+2 -> \+2)[shift]
\+1[close] = \-1
\+2[close] = \+1
\+3[close] = \+2
\-1[shift] = \-2
\-2[shift] = \-3
(\+2 -> \+2)[close +2]
\+2[close +2] -> \+2[close +2][shift]
\-1 -> \-2
(\+2 -> \+2)[close][close]
(\+2[close] -> \+2[close][shift])[close]
(\+2[close][close] -> \+2[close][shift][close][shift])
(A : Type) -> (\+2 -> \+2)[close +2]
\-1[open t] = t
\-(n + 1)[open t] = \-n
\+n[+n close -m] = \-m
l |- (A -> B)[s]
l |- A[s] -> B[open \+l][s][shift]
(\+2 -> \+2)[close +2]
(\+2[close +2] -> \+2[open \+l][close +2][shift])
(\+2[close +2] -> \+2[close +2][shift])
[] [] |- \+2[open \+l][close +2][shift]
[open \+l; noop; shift] [noop; close +2; noop] |- \+2
[open \+l; noop; shift] [noop; close +2; noop] |- \+2
[open \+l; shift] [close +2] |- \+2
[shift] [close +2] |- \-1
\+2[close][close] -> \+2[open \+l][close][open \+l][close]
\-2 -> \+1[close][open \+l][close]
(a -> b)[s]
(a[s] -> b[lift(s)])
[] |- (A : Type) -> A\-1
[] |- (A : Type) -> _A
[open \+2] |- (A : Type) -> A\-1
[open \+2] |- (A : Type) -> _A
(\+2 -> \+2)[close +2]
\+2[close +2] -> \+2[open \+l][close +2]
// TODO: exception?
\-1 == \-1
\-(n + 1)[lift(s)] == \-n[s][shift]
(\+2 -> \+2)[close +2]
(\+2[close +2] -> \+2[lift(close +2)])
(\+2[close +2] -> \+2[close +2][shift])
(\-1 -> \-2)[open A]
(\-1[open A] -> \-2[lift(open A)])
(\-1[open A] -> \-1[open A][shift])
(A : Type) -> (\+1 -> \+1)[close]
(A : Type) -> \+1[close] -> \+1[close][shift]
(A : Type) -> \-1 -> \-2
((A : Type) -> \-1 -> \-2)
(\-1 -> \-2)[1 . shift]
((A : Type) -> \+2 -> \+2)[shift]
((A : Type) -> \+3 -> \+3)
0 [] { 3 : 3 } |- \+3
[] |- (\+2 -> \+2)[close +2]
[close +2] |- \+2 -> \+2
[] |- (\+2 -> \+2)[close +2]
[close +2] |- \+2 -> \+2
\+2[close +2] -> \+2[open \+l][close +2]
[] |- (\+2 -> \+2)[close +2]
[close +2] |- \+2 -> \+2
[\+1] [+2] |- \-1
(\-1 -> \-2)[open ]
(A : Type) -> (\+2 -> \+2)[close +2]
[] |- (\+2 -> \+2)[close +2]
[close +2] |- \+2 -> \+2
[open +l; lift([close +2])] |- \+2
(λa)[s]
λ(a[+l . ])
[open +l; lift([close +2])] |- \+2
[open +l; lift([close +2])] |- \+2
[open \+l] [] |- \+2
[\+1] [+2] |- \-1 -> \-2
(\-1 -> \-2)[id]
\-1[id] -> \-2[open \+l][id][shift]
\-1 -> \-2
(λa)[s]
λ(a[+l . ])
[] |- \-1[open a[open b]]
[a[open b]] |- \-1 ~> a[open b]
[open b; _] |- (λ-2)
[] |- \-1[open a[open b]]
// fast / naive enough?
[open \+2; open \+1] {} |- \+1[close +1][open \+1]
[open \+1; open \+2; open \+1] {} |- \+1[close +1]
[open \+1; open \+2; open \+1] { 1 : [3] } |- \+1
[open \+1; open \+2; open \+1] [] |- \-1
[_; _; _] [] |- \+1
[open \+2; open \+1] {} |- \+1[open \+1][close +1][open \+1]
[open \+1; open \+2; open \+1] {} |- \+1[open \+1][close +1]
[open \+1; open \+2; open \+1] { 1 : [3] } |- \+1[open \+1]
[open \+1; open \+1; open \+2; open \+1] { 1 : [3] } |- \+1
[open \+1; open \+1; open \+2; open \+1] { 1 : [3] } |- \-2
[open \+2; open \+1] { 1 : [2] } |- \+1[open \+1]
[open \+1; open \+2; open \+1] { 1 : [2] } |- \+1
[open \+1; open \+2; open \+1] { 1 : [2] } |- \+1
[open \+2; open \+1] {} |- \+1[close +1][open \+1]
[open \+1; open \+2; open \+1] {} |- \+1[close +1]
[open \+1; open \+2; open \+1] { 1 : 3 } |- \+1
[open \+1; open \+2; open \+1] { 1 : 3 } |- \-1
[open \+1; open \+2; open \+1] { 1 : 3 } |- \+1
[open \+2; open \+1] [none; none] |- \+2[close +2][open \+2]
[open \+2; open \+2; open \+1] [] |- \+2[close +2]
[open \+2; open \+2; open \+1] { 2 : } |- \+2[close +2]
// capture entire stack
[open \+2; open \+1] {} |- \+1[open \+1][close +1][open \+1]
[open \+1; open \+2; open \+1] {} |- \+1[open \+1][close +1]
[open \+1; open \+2; open \+1]
{ 1 : ([open \+1; open \+2; open \+1], {}) } |- \+1[open \+1]
[open \+1; open \+1; open \+2; open \+1]
{ 1 : ([open \+1; open \+2; open \+1], {}) } |- \+1
[open \+1; open \+2; open \+1] {} |- \+1
[open \+1; open \+2; open \+1] {} |- \-1
// shift stack
[open \+2; open \+1] {} |- \+1[open \+1][close +1][open \+1]
[open \+1; open \+2; open \+1] {} |- \+1[open \+1][close +1]
[open \+1; open \+2; open \+1] { 1 : (3, {}) } |- \+1[open \+1]
[open \+1; open \+1; open \+2; open \+1] { 1 : (3, {}) } |- \+1
[open \+1; open \+2; open \+1] {} |- \+1
[open \+1; open \+2; open \+1] {} |- \-1
\+1[open \+1][close +1][open \+1]
\+1[close +1][open \+1]
\-1[open \+1]
\+1
\-1[shift][open \+2][open \+1]
[open \+2; open \+1] |- \-1[shift]
[open \+1] |- \+1
\-1[open a] ~> a
\-(n + 1)[open a] ~> \-n
(λa)[+1 close -1]
λ(a[+l][+1 close -2])
(λa)[+1 close -1]
λ(a[+1][+1 close -2])
s1 λe1 = s2 λe2
lift s1 e1 = lift s2 e2
(λe1)
open t (λλ-2) = λλ-2
[noop; open +2; open +1]
lift s (-1) = -1
lift s (-(n + m)) =
-2[open +1][open +2]
-2[-l open +1]
[+1 close -2]
t[s][]
(λa)[+1 close -2]
λ(a[+l][close +1])
(λa)[close +1]
λ(a[+l][close +1])
lift(, 1) = 1
lift(open +n, n + 1) = shift(s(n))
lift(open +, 1) = 1
lift(open +n, n + 1) = shift(s(n))
lift(s, 1) = 1
lift(s, n + 1) = shift(s(n))
\-1[shift][open \+2]
2 [\+2; \+1] {} |- \+1[open \+1][close +1][open \+1]
2 [\+1; \+2; \+1] {} |- \+1[open \+1][close +1]
2 [\+1; \+2; \+1] { 1 : (2, 3, {}) } |- \+1[open \+1]
2 [\+1; \+1; \+2; \+1] { 1 : (2, 3, {}) } |- \+1
2 [\+1; \+2; \+1] {} |- \-1
2 [\+2; \+1] {} |- (λ\+1)[close +1][open \+1]
2 [\+1; \+2; \+1] {} |- (λ\+1)[close +1]
2 [\+1; \+2; \+1] { 1 : (2, 3, {}) } |- λ\+1
3 [\+2; \+1; \+2; \+1] { 1 : (2, 3, {}) } |- \+1
2 [\+1; \+2; \+1] {} |- \-1
2 [\+2; \+1] {} |- \+1
2 [\+1; \+2; \+1] { 1 : (3, {}) } |- \+1[open \+1]
2 [\+1; \+1; \+2; \+1] { 1 : (2, 3, {}) } |- \+1
2 [\+1; \+2; \+1] {} |- \-1
1 |- λ((\-1 \+2)[close +2])
(λ\+1)[close +1][open \+1]
(λ-1)[close +1] = (λ-1)[close +1]
(-1[+l][close +1][shift]) = (-1[+l][close +1][shift])
(λ+1)[close +1] ~~> λ-2
// colision inside of lambda related to open
(λa)[s]
λ(a[+l][])
closed[s][shift]
\-1[open \+l][shift]
1 2 => x y
1 |- (x => (x\+2 y\-2)[close +2 to -1])[open -1 to y\+1]
// entering a binder requires to shift all free negative variables
// the right side on open is locally closed, so only shift the left
// the left side on close is locally closed, so only shift the right
1 |- x => (x\+2 y\-2)[close +2 to -1][open -2 to y\+1]
1 |- x => (x\+2[close +2 to -1] y\-2[close +2 to -1])[open -2 to y\+1]
1 |- x => (x\-1 y\-2)[open -2 to y\+1]
1 |- x => (x\-1[open -2 to y\+1] y\-2[open -2 to y\+1])
1 |- x => x\-1 y\+1
// should definitely be true
(A : Type) -> \-1 -> \-2 `unify` (A : Type) -> _A -> _A
// solution, open and invoke a level in the context
2 |- (A : Type) -> \-1 -> \-2 `unify` (A : Type) -> _A -> _A
3 |- (\-1 -> \-2)[open -1 to \+3] `unify` (_A -> _A)[open -1 to \+3]
3 |- \+3 -> \+3 `unify` _A -> _A
// should ALWAYS be (y => x => x\-1 y\-2)
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
// follow the steps and you will get to this
l + 2 |- (x\+(l + 2) y\+2)[close +2 to -2][open -2 to \+(l + 1)]
// what happens if l is 0?
2 |- x\+1 y\+1
// what happens if l is 1?
3 |- x\+3 y\+3
2 |- (x\+2 \+2)[open -2 to \+1][close +2 to -2]
2 |- (x\-2 y\-2)
l |- (y => (x => x\-1 y\+2)[close +2 to -1 at l + 1])
l + 1 |- (x => x\-1 y\+2)[close +2 to -1 at l + 1][open -1 to \+(l + 1)]
l + 2 |- (x\-1 y\+2)[open -1 to \+(l + 2)][close +2 to -2 at l + 1][open -2 to \+(l + 1)]
l + 2 |- (\+(l + 2) y\+2)[close +2 to -2 at l + 1][open -2 to \+(l + 1)]
// what happens if l is 0?
2 |- (\+2 y\+2)[close +2 to -2 at l + 1][open -2 to \+(l + 1)]
// should ALWAYS be (y => x => x\-1 y\-2)
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
l + 1 |- (x => x\-1 y\+2)[close +2 to -1][open -1 to \+(l + 1)]
l + 2 |- (x\-1 y\+2)[open -1 to \+(l + 2)][close +2 to -2][open -2 to \+(l + 1)]
l + 2 |- (x\-1 y\+2)[open -1 to \+(l + 2)][close +2 to -2][open -2 to \+(l + 1)]
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
// should ALWAYS be (y => x => x\-1 y\-2)
l |- (y => (x => x\-1 y\+1)[close +1 to -1])
l + 1 |- (x => x\-1 y\+1)[close +1 to -1][open -1 to \+(l + 1)]
l + 2 |- (x\-1 y\+1)[open -1 to \+(l + 2)][close +1 to -2][open -2 to \+(l + 1)]
l + 2 |- (x\-1 y\+(l + 1))[open -1 to \+(l + 2)][close +1 to -2][open -2 to \+(l + 1)]
// l = 0
2 |- (x\-1 y\+1)[open -1 to \+2][close +1 to -2][open -2 to \+1]
2 |- (x\+2 y\+1)
// l = 1
3 |- (x\-1 y\+1)[open -1 to \+3][close +1 to -2][open -2 to \+2]
3 |- (x\+3 y\+2)
// should ALWAYS be (y => x => x\-1 y\-2)
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
l + 1 |- (x => x\-1 y\+2)[close +2 to -1][open -1 to \+(l + 1)]
l + 2 |- (x\-1 y\+2)[open -1 to \+(l + 2)][close +2 to -2][open -2 to \+(l + 1)]
// l = 0, leads to [close +2] at level 1, which is weird
// reminds me of escaping the scope
1 |- (x => x\-1 y\+2)[close +2 to -1][open -1 to \+1]
1 |- (x => x\-1 y\+2)[close +2 to -1][open -1 to \+1]
3 |- x\+3 y\+2
// should ALWAYS be (y => x => x\-1 y\-2), when l > 1
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
(y => (x => x\-1 y\+2)[close +2 to -1])
l + 2 |- (x\-1 y\+(l + 1))[open -1 to \+(l + 2)][close +1 to -2][open -2 to \+(l + 1)]
(x\-1 y\+(l + 1))[open -1 to \+(l + 2)][close +1 to -2][open -2 to \+(l + 1)]
(x\+(l + 2) y\+l)
(x\+(l + 2) y\+(l + 1))
(x\+(l + 2) y\+(l + 1))[close +(l + 2) to -1]
(x\+(l + 2) y\+(l + 1))
l |- (y => (x => x\-1 y\+2)[close +l to -1])
l + 1 |- (x => x\-1 y\+2)[close +l to -1]
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
l + 2 |- (x\+(l + 2) y\+(l + 1))
l + 2 |- (x\-1 y\+(l + 1))[open -1 to \+(l + 2)][close +1 to -2][open -2 to \+(l + 1)]
(x\+(l + 2) y\+(l + 1))[close +(l + 2) to -1]
(x\-1 y\+(l + 1))[open -2 to +]
//
l |- (y => (x => x\-1 y\+2)[close +2 to -1])
l + 2 |- (x\+(l + 2) y\+(l + 1))
l |- (y => (x => x\-1 y\+(l + 2))[close +(l + 2) to -1])
l + 1 |- (y => (x => x\-1 y\+(l + 2))[close +(l + 2) to -1])
//
l + 2 |- (\-1 \+2)[open -1 to \+(l + 2)][close +2 to -2][open -2 to \+(l + 1)]
l + 2 |- (\-1 \+2)[open -1 to \+(l + 2)][close +2 to -2][open -2 to \+(l + 1)]
l + 2 |- \+(l + 2) \+2[open -1 to \+(l + 2)]
//
l |- (y => (x => x\-1 y\+(l + 2))[close +(l + 2) to -1])
l + 1 |- (x => x\-1 y\+(l + 2))[close +(l + 2) to -1][open -1 to +(l + 1)]
l + 2 |- (x\-1 y\+(l + 2))[open -1 to +(l + 2)][close +(l + 2) to -2][open -2 to +(l + 1)]
0 |- (y => (x => x\-1 y\+1)[close +1 to -1])
0 |- (y => (x => x\-1 y\+1)[close +1 to -1])
l |- (y => (x => x\-1 y\+(l + 1))[close +(l + 1) to -1])
l |- (z = _; y => (x => x\-1 y\+(l + 1))[close +(l + 1) to -1])
(z = _; y => (x => x\-1 y\+1)[close +1 to -1])
0 [] [] {} |- (y => (x => x\-1 y\+1)[close +1 to -1])
1 [back] [open \+1] {} |- (x => x\-1 y\+1)[close +1 to -1]
1 [back; back] [open \+1] { +1 := ({}, -1 ~> \+1) } |- x => x\-1 y\+1
2 [] [open \+2; open \+1] { +1 := ({}, -1 ~> \+1) } |- x\-1 y\+1
2 [] [open \+2; open \+1] { +1 := ({}, -1 ~> \+1) } |- x\+2 y\+1
0 [] [] |- (y => (x => x\-1 y\+1)[close +1 to -1])
0 [] [] |- (y => (x => x\-1 y\+1)[close +1 to -1])
0 [] [] {} |- (y => (x => x\-1 y\+1)[close +1 to -1])
1 [back] [open \+1] {} |- (x => x\-1 y\+1)[close +1 to -1]
1 [back; back] [open \+1] { +1 := ({}, -1 ~> \+1) } |- x => x\-1 y\+1
(y => (x => x\-1 y\+2)[close +2 to -1])
(y => (x => x\-1 y\+1)[close +1 to -1])
(y => (x => (x\+2[close +2 to -1]) y\+1)[close +1 to -1])
(y => (x => x\-1 y\l+2)[close l+2 to -1])
(y => (x => x\-1 y\l+2)[close l+2 to -1])
[] [] |- (y => (x => x\-1 y\+1)[close +1 to -1])
[] [\+1] |- (x => x\-1 y\+1)[close +1 to -1]
[] [\+1] |- x => x\-1 y\+1
[] [\+2; \+1] |- x\-1 y\+1
[y\+1] [\+2; \+1] |- x\+2
[] [\+2; \+1] |- y\+1
[] [] |- λ(λ(\-1 \+1))[+1 := -1]
[] [\+1] |- (λ\-1 \+1)[+1 := -1]
[] [\+1] |- λ\-1 \+1
[] [\+2; \+1] |- \-1 \+1
[\+1] [\+2; \+1] |- \-1 ~> \+2
[] [\+2; \+1] |- \+1
[] [\+1] |- (x => x\-1 y\+1)[close +1 to -1]
[] [\+1] |- x => x\-1 y\+1
[] [\+2; \+1] |- x\-1 y\+1
[y\+1] [\+2; \+1] |- x\+2
[] [\+2; \+1] |- y\+1
[] |- _A[-1 := \+2] === +2
[] |- _A === +2[+2 := -1]
[] |- _A === \+1[+1 := \-1]
[] |- _A === \-1
l |- λ(_A λ(\-1 \+1))[+1 := -1]
0 |- (x = _; y => (x => x\-1 y\+2)[)
0 |- ((z => y => (x => x\-1 y\+2)[close +2 to -1]) _)
((z => y => (x => x\-1 y\+2)[close +2 to -1]) _)
(z => y => (x => x\-1 y\+2)[close +2 to -1])[open -1 to _]
(z => y => (x => x\-1 y\-2))
y => _A[close +2 to -1] `unify` x => x\-1
0 |- y => _A[close +2 to -1] `unify` x => x\-1
1 |- x => \+1[close +2 to -1]
(((1 z) => (2 y) => ((3 x) => x\-1 y\+2)[close +2 to -1]) _)
((2 y) => ((3 x) => x\-1 y\+2)[close +2 to -1])[open -1 to _]
((1 y) => ((2 x) => x\-1 y\+2[close +2 to -2][open -3 to _]))
(1 y) => ((2 x) => x\-1 y\-2)
(((1 z) => (2 y) => ((3 x) => x\-1 y\+2)[close +2 to -1]) _)
((2 y) => ((3 x) => x\-1 y\+2)[close +2 to -1])[open -1 to _]
y => _A[close +2 to -1] `unify` x => x\-1
l |- (A : Type) -> (_A -> _A)[close +(l + 1) to -1] `unify` (A : Type) -> A\-1 -> A\-2
l + 1 |- (_A[close +(l + 1) to -1] -> _A[close +(l + 1) to -2]) `unify` A\-1 -> A\-2
l + 1 |- (_A[close +(l + 1) to -1]) `unify` A\-1
l + 1 |- _A `unify`
l + 1 |- A\-1[open -1 to \+(l + 1)][close +(l + 1) to -2] `unify` A\-2
l + 1 |- A\-2 `unify` A\-2
A\-2[open -2 to \+(l + 1)][open -1 to \+(l + 1)]
A\-2[open \+(l + 1)][to \+(l + 2)]
(A : Type) -> (A\+1 -> A\+1)[from +1]
((A : Type) -> A\-1)[to \+2]
(A : Type) -> A\+1[from +1] -> A\+1[lift(from +1)]
(A : Type) -> A\+1[from +1] -> A\+1[lift(from +1)]
A\+1[from] = A\-1
A\+2[from] = A\+1
lift s \-(n + 1) = s \-n
lift s +n = s +n | \-m => \-(m + 1)
((B : Type) -> (A\-2 B\-1))[to f]
((B : Type) -> (A\-2 B\-1)[lift(to f)])
((B : Type) -> A\-2[lift(to f)] B\-1[lift(to f)])
((B : Type) -> A\-1[to f] B\-1)
((B : Type) -> f B\-1)
[to \-1; to a; to b]
[from; from; none]
l |- \+1
(B : Type) -> (A\-2[open f] B\-1)
[close; close; close] |- (A : Type) -> A\+4[close]
[close; close; close; close] |- A\+4 ~> A\-1
lift s +(n + 1) = s +n | \-m => \-(m + 1)
0 |- λ(λ+1)[close] ~~> λλ-2
0 |- λ(λ+1)[close]
λλ+1[lift close]
λλ+1[close][shift]
λλ-2
lift s l \-(n + 1) = s +l \-n
lift s l +n = s +(l + 1) +n | \-m => \-(m + 1)
close l +l = \-1
l |- λ(λ+(l + 1))[close] ~~> λλ-2
l |- λ(λ+(l + 1))[close]
λλ+(l + 1)[lift close]
λλ-2
0 |- (x = _; (λ(λ+2)[close])[close]) ~~> λλ-2
1 |- λ(λ+2)[close] ~~> λ(λ+2[lift(close)])
1 |- λ(λ+2)[close] ~~> λ(λ+1[close])
λ(_A _A)[close] `unify` λ(+1 +1)[close]
λ(_A _A)[close] `unify` λ(+1 +1)[close]
((A : Type) -> A\+4[close])
A\+1[close] = A\-1
A\+2[close] = A\+2
A\+2[lift(close)] = A\-2
A\+3[lift(lift(close))] = A\-3
((B : Type) -> (A\-2 B\-1))[to f]
(λ(λ+2)[close])[close] ~~> λλ-2
λ(λ+2)[close][lift close]
λλ+2[lift close][lift (lift close)]
0 |- λ(λ+1)[close]
λλ+1[lift close]
λλ+1[close][shift]
λλ-2
0 |- (λ(λ+2)[close])[close]
1 [] [close +1] |- λ(λ+2)[close]
1 [open \-1] [close +1] |- (λ+2)[close]
1 [open \-1] [close +1] |- (λ+2)[close]
λ.(λ.+2[close])[close]
λ.(λ.+1[lift close])
λ.(λ.-2)
\-1[lift s] = \-1
\-(n + 1)[lift s] = \-n[s][shift]
a[lift s]
// relevant property is that x doesn't appear in s
a[open x][s][close x]
-1[open x][s][close x] = x[s][close x] = x[close x] = -1
-2[open x][s][close x] = -1[s][close x] =
-1[close y][close x] = -1[close x] = -2
-1[open a][close x] = a[close x] = a
+y[open x][s][close x] = +y[s][close x]
+y[open _][close x] = +y
+y[close y][close x] = -1[close x] = -2
\-1[incr][-2 open a][decr] = \-2[open a][decr] = \-2[decr] = \-1
\-2[incr][open a][decr]
λ.(λ.-2)
+2[close][close] = \-1
[] [close] |- λ(λ+2)[close]
[free] [close] |- (λ+2)[close]
[free] [close; close] |- λ+2
[free; free] [close; close] |- +2
open t \-1 = t
open _ \-(n + 1) = \-n
close \+1 = \-1
close \+(n + 1) = \+n
lift _ \-1 = \-1
lift s \-(n + 1) = s \-n
lift s \+n = s +n | \-m => \-(m + 1)
λ.(λ.+2[close])[close]
λ.λ.+1[lift close]
λ.λ.-2
(λ.(λ.(λ.+2[close])[close])[close]) _
(λ.(λ.+2[close])[close])[close][open _]
λ.(λ.+2[close])[close][lift close][lift (open _)]
λ.(λ.-2)[lift close][lift (open _)]
(λ.(λ.(λ.+3[close])[close])[close]) _
(λ.(λ.+3[close])[close])[close][open _]
λ.(λ.+2[close])[close]
λ.(λ.+2[close][lift close])
λ.(λ.-2[lift close])
λ.(λ.-1)
λ.λ.(+2 +1)[close]
(λ+1.λ+2.+3) a
(λ.+2[close +2])
Button
: () -[Database]> React.Component
= () => {
const x = get();
return (<div> {x} </div>)
};
## Chapter {{pinned}}
### Abc
BBBBB
### Def
AAAAA
#### Def concepts
... ai puts here
pred (succ x)
- max term size
- locality / proxy accumulate de-bruijin
- linearity / variable grading
- total number of reduction
(x => M) N
M[x := N]
(x => x x) N(10)
N N
Github find all PR / patches, trim many features, rank developers,
(λ.(λ.(λ.+1))[close +1]) a
(λ.(λ.+1))[close +1][open a]
λ.(λ.+1)[lift (close +1)][lift (open a)]
λ.λ.+1[lift (lift (close +1))][lift (lift (open a))]
λ.λ.-3[lift (lift (open a))]
λ.λ.-1[open a]
λ.λ.a
(λ.(λ.(λ.+3[close +3]))) a
(λ.(λ.+3[close +3]))[open a]
λ.(λ.+3[close +3])[lift (open a)]
λ.λ.+3[close +3][lift (lift (open a))]
λ.λ.-1[lift (lift (open a))]
λ.λ.-1
0 |- (λ.(λ.(λ.+3[close +3]))) a
0 |- (λ.(λ.+3[close +3]))[open a]
[] [] |- (λ.(λ.+3[close +3]))[open a]
0 [] [] |- (λ.(λ.(λ.+3))) a
0 [] [] |- (λ.(λ.+3))[a]
1 [a] [1] |- λ.(λ.+3)
2 [a; +2] [1; 2] |- λ.+3
3 [a; +2; +3] [1; 2; 3] |- +3
λ(1).+1 +1
λ(1)._A _A
(x = _; y = λ(2).+2 +2; +3)
(λ(1).(λ(2).+2) (λ(2).+2 +2)) _
((λ(2).+3) (λ(2).+2 +2))[1 | _]
((λ(2).+3) (λ(2).+2 +2))[1 | _]
(+2[2 | λ(2).+2 +2])[1 | _]
+2[2 | λ(2).+2 +2][2 | _]
+2[2 | λ(2).+2 +2][2 | _]
(λ(1).λ(2).+2 +2) _
∀(2).+2 +2
[-1] |- (λ.(λ.+3))[open a]
(λ(1).(λ(2).(λ(3).+3))) a
0 [] [] |- (λ(2).(λ(3).+3))[a]
1 [a] [a] |- λ(2).λ(3).+3
2 [a; +2] [1; 2] |- λ(3).+3
3 [a; +2; +3] [1; 2; 3] |- +3
(λ(2).(λ(3).+3))[open a]
v <= l
-------
l |- +v
v |- b
------------
l |- λ(v). b
[] |- (λ(3).(λ(4).+2))[2 | a]
[] |- (λ(3).(λ(4).+2))[2 | a]
(λ(1).+1 +1) (λ(2).+2)
(λ(2).+2 +2)
(+2 +2)[2 := λ(1).+1]
(λ(1).+1) (λ(1).+1)
+1[1 := λ(1).+1]
λ(1).+1
x = _;
(λ(1).+1 _A)
[] |- λ(1).+1 === λ(2).+2
[] |- λ(1).+1 === [] |- λ(2).+2
[-1] |- +1 === [] |- λ(2).+2
λx.a `unify` λy.b
a[x := z] `unify` b[y := z]
_A `unify` b[y := x]
[] |- λ.+1[close +2] === [] |- λ.+2[close +2]
[] |- λ.+1[close +1] === [] |- λ.+2[close +2]
[] |- +1[close +1] === [] |- +2[close +2]
[close +1] |- +1 === [close +2] |- +2
[close +1] |- -1 === [close +2] |- -2
[] |- λ.(+1 (λ.+1))[close +1] === [] |- λ.(+3 (λ.+3))[close +3]
[] |- λ.(_A (λ._A))[close +1] === [] |- λ.(+3 (λ.+3))[close +3]
[] |- λ.(_A (λ._A))[close +1] === [] |- λ.(+3 (λ.-2))[close +3]
[] |- (_A (λ._A))[close +1] === [] |- (+3 (λ.-2))[close +3]
[close +1] |- _A (λ._A) === [close +3] |- +3 (λ.-2)
[close +1] |- _A === [close +3] |- +3
_A := +3[close +3][open \+1]
[close +1] |- λ.+3[close +3][open \+1] === [close +3] |- λ.-2
[lift (close +1)] |- +3[close +3][open \+1] === [lift (close +3)] |- -2
[close +3; open \+1; lift (close +1)] |- +3 === [lift (close +3)] |- -2
[open \+1; lift (close +1)] |- -1 === [lift (close +3)] |- -2
[lift (close +1)] |- +1 === [lift (close +3)] |- -2
[] |- -2 === [lift (close +3)] |- -2
[lift [close +1]] |- +2[close +2][open \+1] === [lift [close +2]] |- +2
[close +2; open \+1; close +1] |- +2 === [close +2] |- +2
[] |- λ.(_A (λ._A))[close +1] === [] |- λ.(-1 (λ.+3))[close +3]
[] |- (_A (λ._A))[close +1] === [] |- (-1 (λ.+3))[close +3]
[close +1] |- _A (λ._A) === [close +3] |- -1 (λ.+3)
[close +1] |- _A === [close +3] |- -1
_A := -1[close +3][open \+1]
[close +1] |- λ.-1[close +3][open \+1] === [close +3] |- (λ.+3)
[lift (close +1)] |- -1[close +3][open \+1] === [lift (close +3)] |- +3
[close +3; open \+1; lift (close +1)] |- -1 === [lift (close +3)] |- +3
[] |- -2 === [] |- -2
line 15, col 2
> f expr expr2
^ ^
Message
expected : Option Int
received : Option String
[@mode dynamic]
l => l.map(x => x + 1);
l => List.map(l, x => x + 1);
f = x => print(cast x);
Id = (A : Type) -> A;
x : Id Int = _;
(x : _A);
[] |- _A === Id Int
expected : \-1[(open \+2) :: lift (open \+1)]
received : \-2[(open \+3) :: lift ((open \+2) :: lift (open \+1))]
expected : \-0[(open \+4) :: lift ((open \+3) :: lift ((open \+2) :: lift (open \+1)))]
received : \-0[(open \+3) :: lift ((open \+2) :: lift (open \+1))]
expected : \-0[(open \+4) :: lift ((open \+3) :: lift ((open \+2) :: lift (open \+1)))]
received : \-0[(open \+3) :: lift ((open \+2) :: lift (open \+1))]
expected : ((x : ) -> \-1)[(open \+3) :: lift ((open \+2) :: lift (open \+1))]
received : ((x : ) -> \-1)[(open \+2) :: lift (open \+1)][(open \+3) :: lift ((open \+2) :: lift (open \+1))]
annot : ((A : \+1) -> (x : \-0[(open \+4) :: lift ((open \+3) :: lift ((open \+2) :: lift (open \+1)))]) -> \-1)[(open \+3) :: lift ((open \+2) :: lift (open \+1))]
x : IO(Result(String, Error))
x : Result(IO(String), Error)
Eff l r = Raw_eff (sort_uniqe l) r;
x : Eff [IO; Result] String
x : Eff [Result; IO] String
x : Eff [Random] String;
() = format();
(x : Nat 1) => x + x;
Socket : {
connect : () -> $Socket;
close : $Socket -> ();
};
() => (
x = Socket.connect();
Socket.close(x);
);
x => y => x;
x => y => y;
r0 : Linear
r1 : Linear
(three, r1) = add(r0, r1);
Array : {
$Array : (A : Type) -> Type;
make : () -> $Array Int;
get : {A} -> (i : Nat, arr : Array A) -> (Array A, Option A);
Read_only_array : _;
split : (i : Nat, arr : Array A) -> (List (Read_only_array A i arr))
merge : (l : List (Read_only_array A i arr)) -> Array A;
} = _;
f = arr0 => (
(arr1, x) = Array.get(0, arr0);
(arr2, y) = Array.get(1, arr1);
)
find : () -> Eff [Database] (List User);
integration()
@debug(find())
(A : _) -> _B[close +3] === (A : _) -> \-1
(A : _) -> _B[close +3] === (A : _) -> \-1
_B === \-1[open \+3]
(A : Type) -> A\+2 === (A : Type) -> A\+2
(A : _) -> (_C ((B : _) -> _C))[close +2] === (A : _) -> (_D ((B : _) -> \-2))
(_C ((B : _) -> _C))[close +2] === (_D ((B : _) -> \-2))
((B : _) -> _C)[close +2] === (B : _) -> \-2
_C[lift (close +2)] === \-2
_C === \-2[lift (open \+2)]
_C === \-1
_C[shift] === \-2
_C === \-2[lower]
_A[lift s] === \-2
_A === \-2[lift (not s)]
_A[lift (close +n)] === \-2
_A === \-2[lift (open \+n)]
\-2[lift (open \+n)][lift (close +n)] === \-2
\+n[lift (close +n)] === \-2
\-2 === \-2
_A[lift (open +n)] === \+n
_A === \+n[lift (close +n)]
\+n[lift (close +n)][lift (open +n)] === \+n[lift (close +n)]
\-2[lift (open +n)] === \+n[lift (close +n)]
\-2[lift (open +n)] === \+n[lift (close +n)]
_A[lift (close +n)] === \+n
_A[shift] === \-2
_A[shift] === \-2
_A === \-2[1 . id]
(A : Type) -> _A
l := t
expected : ((x : \+1[id]) -> \+1[close +3])[id]
received : ((_x0 : \+3[id]) -> \+3[id])[id][lift id][open \+3][+3 := \+1][id]
_A[close \+2][open \+3] === +2
_A === +2
_A[close \+2][open \+3] === +2
_A === -1
_A === +1[open +2]
_A[x := N] === x
x === x
_A[+2] ===
x[x := N] === x
(λλ_A[lift (1 1)] === λλ2)
(λ_A[lift (1 1)] === λ2)
(_A[lift (1 1)] === 2)
(x => _A) N === y
_A[x := N] === x
Γ,Δ1 |- A Γ,Δ2 |- B
----------------------
Γ |- A === B
_A[open +2][close +2] = -1
_A = -1[open +2][close +2]
Γ |- e : A Γ |- r[x := e] : B
------------------------------
Γ |- x = e; r : B
(Id = (A : Type) => A; )
m.n
_::n(m)
m.n a b
_::n
Nat = (A : Type) -> (z : A) -> (s : (x : A) -> A) -> A;
(zero : Nat) = A => z => s => z;
(succ : (n : Nat) -> Nat) = n => A => z => s => s (n A z s);
(add : (n : Nat) -> (m : Nat) -> Nat) = n => m => n Nat m succ;
(mul : (n : Nat, m : Nat) -> Nat) = n => m => n Nat zero (add m);
one = succ zero;
two = succ one;
four = mul two two;
eight = mul two four;
sixteen = mul two eight;
byte = mul sixteen sixteen;
byte String "zero" (_ => @native("debug")("hello"))
x.f === _::f(x)
x.f (1, 2) === _::f(x)(1, 2)
add = (!n : Nat, !m : Nat) => n + m;
id = {A} => (x : A) => x;
add = (!n : Nat, !m : Nat, log : Option Bool) => n + m;
x = add (n = 1, m = 2);
(1, 2) : (_A : Nat, _B : Nat);
(_A : Nat, _B : Nat) === (n : Nat, m : Nat)
(_A : Nat, _B : Nat) === (!n : Nat, !m : Nat)
(x = 1, y = 2) : (x : Nat, y : Nat);
Int : {
@Int : Type;
show : (i : @Int) -> () -> String;
};
ind_bool : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
ind_bool : (b : Bool (i + 1)) ->
(P : Bool i -> Type) -> P true -> P false -> P (lower b);
Consistency = Soundness + Strong Normalization;
(Type 0 : Type 1)
(Type n : Type (n + 1))
id = (A : Type 1) => (x : A) => x;
id (Type 1)
ind_bool : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b = _;
Γ, x : @self(x). T |- T : Type
------------------------------
Γ |- @self(x). T : Type
Γ, x : @self(x). T |- M : T[x := @fix(x). M]
--------------------------------------------
Γ |- @fix(x). M : @self(x). T
Γ |- M : @self(x). T
--------------------------
Γ |- @unroll M : T[x := M]
two = z => s => s (s z);
two = z => s => s z (x => s x);
three = z => s => s z (x => s x s)
id = (x : 'A) => x;
((x : 'A) -> 'A)
id : (x : 'A) -> 'A;
sum : (x : Int, y : Int) -> Int;
sum : (f : (x : Int, y : Int)) -> Int;
id (1);
sum 1 2;
sum (1, 2);
(x = (1, 2); sum(...x))
(sum((1, 2)))
(x, y) = id(_ = (1, 2));
(x, y) =>
ind : (b : Bool, P : Nat -> Type) -> (x : P true, y : P false) -> P b;
sum : (x : Int) -> (y : Int) -> Int;
sum 1 _
?sum 1 _
y => ?sum 1 _
id(1, 2) : (1, 2)
add a b = c;
// named return
(x : Int) -> (x : Int)
(Bool : Type) -> (true : Bool) -> (false : Bool) ->w
(Bool : Type) & {
true : Bool;
false : Bool;
case : {A} -> (pred : Bool, then : A, else : A) -> A;
} = _;
add 1 ~> add 1
add 1 2 ~> 3
Γ |- A : Type
--------------------------
Γ |- @frozen(A) : Type
Γ |- M : A
--------------------------
Γ |- @freeze M : @frozen A
Γ |- M : @frozen A
--------------------
Γ |- @unfreeze M : A
---------------------------
@unfreeze (@frozen M) === M
T =
(R : Type) ->
((A : Type) ->
(x : A) ->
(to_string : A -> String) ->
R) -> R;
M : T = _;
to_string : ((A : Type) -> M ) -> String;
M : {
Nat : Type;
one : Nat;
to_int : Nat -> Int
} = @nominal(key => (
Nat = @frozen(key, Int);
one = @freeze(key, 1);
to_int = x => @unfreeze(key, x);
));
T = @nominal(key => (
Nat = @frozen(key, Int);
one = @freeze(key, 1);
)).Nat;
M.one
(2 x : Int) => x + x
call v f = f v
(A : Type) -> A
mono = w => x => y => (id => w (k x) (k y)) (x => x);
(a : _A\+1) => (A : Type) => (b : _B\+2) =>
(x => x) 1
((2 x : _A & _B) => (x : _A) + (x : _B))
(x0 : Int) => (x1 : Int) => x0 + x1
Nat (G : Grade) = (A : Type) -> (1 z : A) -> (G s : (1 A) -> A) -> A;
(x : Nat) => x Nat zero (acc => acc);
|- Type : Type
Γ |- e : A : Type
(('G + 1) x : @rec T. ('G x: T) -> _) => x x
(x : @rec T. (x : T) -> _) => x x
((x : A) => x) : ((x : A) -> A) : Type
Γ |- e : A : Type
x = Type;
-----------------
ctx, x : A |- x : A
ctx |- func : A -> B ctx |- arg : A
----------------------------------
ctx |- func arg : B
-----------------------------------------
ctx |- (x => body) arg === body[x := arg]
----------------------------------------
ctx | setState |- setState(false) === ()
My_button = (label : String) => <Button>{label}</Button>;
My_button label
My_button =
ctx |- label : String
--------------------------------
ctx |- <Button>{label}</Button>
ctx |- My_button : String -> DOM ctx |- label : String
---------------------------------------------------------
ctx |- My_button label === <Button>{label}</Button>: DOM
ctx |- label : String
-------------------------------
ctx |- <Button>{label}</Button>
My_button = (label : String) => <Button>{label}</Button>;
(A : Type) -> _A -> _B === (A : Type) -> _A -> _B
(A : Type) -> _A[close +2] === (A : Type) -> A\-1
_A[open \+2 \+2][close +2] === -1
_A[close +2] === +2
+2 |- (λ_A[close +1]) +2 === _B
+2 |- _A[close +1][open +2] === _B
+2 |- _A[close +1] === _B[close +2]
+2 |- _A === _B[close +2][open +1]
+2 |- _A === _B[close +2][open +1]
+2 |- (λ_A) +2 === _B
+2 |- _A[open +2] === _B
+2 |- _A === _B[close +2]
_B[close +2][open +1] === +2
_B === +2[open +2]
_B[close +1] === +2[open +2]
_B[close +2] === +2
_B[close +2] === +2
_B[open +2] === +2
[y] |- (x => _A) y === _B
[y] |- _A[x := y] === _B
[y] |- _A === _B[y := x]
unify = a => b => (k => (_ = k a); k b) (x => x);
P => y => z => (f : (x : _) -> P _A) => (g : P _B) =>
unify (f y : P (_A[x := y])) g
(P (_A[x := y]) : P _B)
a : P (_B[y := x])
a : P y
_B[y := x] == y
_A[x := y] == _B
_A[x := y] == _B[y := x]
P => y => z => (f : (x : _) -> P _A) => (
_ : P _B = (f y : P (_A[x := y]));
// _A === _B[y := x]
(f z : P y)
);
P => y => z => (f : (x : _) -> P _A) => (
_ : P _B = (f y : (P _A)[x := y]);
// _A === _B[y := x]
(f z : P y)
);
(P _A)[x := y] === P y
P (_B[y := x][x := z]) === P y
_B[y := x][x := z] === y
// I think this cannot happen
P => y => z => (f : (x : _) -> P _A) => (
_ : P _B = (f y : P (_A[x := y]));
// _A === _B[y := x]
(f z : P y)
);
_B[y := x] == y
_B[y := x] == y
_B[close +2] === +2
_A[x := y] == y
_A[x := y][y := x] == y[y := x]
_A == x
l |- _A == r |- _B
_A := _C[!r]
_B := _C[!l]
l |- _C[!r] == r |- _C[!l]
l . !r |- _C == r . !l |- _C
_C == _C
_C[l][!r] == _C[r][!l]
_C[l][l] == _C[r][r]
_C[l][!r][l] == _C[r]
_C
x[close +3][open +3][close +3]
Γ, x : Int |- xy : Int
(f => y => ) (x => x)
((x => x) y)[y := z]
(x => x[y := z]) y[y := z]
(x => x) z
(x = y; x)[y := z]
(x = y[y := z]; x[y := z])
(x = z; x)
(x = y; x[y := z])
(x = y; x[y := z])
x[y := z][x := y]
(x = y; equal x y)
(equal x y)[x := y]
x === y
one = s => z => s z;
two = s2 => s1 => z => s2 (s1 z);
Nat 'n = (A : Type) -> ('n f : A -> A) -> A -> A;
Bool (n : Grade) =
(A : Type) -> (B : Type) -> (A -> B) -> A -> B
true = x => y => x y;
false = x => y => y;
(A : Type)
Type n
(x : Int 'n) -> (y : Int 'n) -> Int 'n
Nat =
union
(case "z" end)
(case "s" (cell self) end)
close;
Bool =
| (tag : #true)
| (tag : #false);
Either A B =
| (tag : "left", payload : A)
| (tag : "right", payload : B);
| ("left", a) => _
| ("right", b) => _
Either A B = (tag : Bool, payload : tag Type A B);
| (true, a) => _
| (false, b) => _
Either A B =
| True(payload : A)
| False(payload : B);
| True(a) =>
| False(b) => _
data%Bool =
| true
| false;
x = #true;
Nat =
| (tag : "z")
| (tag : "s", pred : Nat);
"z" : Nat
("s", ("z", ()))
Nat =
| Z | S (n : Nat);
1 + 2 : Int _a
1 : Int _n
((A : Type 0) => (x : A 1) => x) : Type 15;
NONCE, auto retry
VERSION
TRANSACTION
LOGIN
PERMISSION
SECURITY
WEBSOCKET
STATEFUL APIs
User and Post
Both indexed by User.id
{
}
Workers + Database
storage@User = {
@index id : @increment Nat;
name : String;
};
User : {
insert : _ -[DB.write "user"]> ();
find_by_id : _ -[DB.read "user.id"]> ();
} = _;
@Routes = [
POST "/users" =
{ name : String; } => User.insert { name = name; };
GET "/users/:id" =
{ id : Nat; } => User.find_by_id id;
GET "/users" =
() => User.list ();
];
test@routes = [
POST "/users" { name = "EduardoRFS"; }
expected { id = 0; name = "EduardoRFS" };
GET "/users/0"
expected { id = 0; name = "EduardoRFS" };
];
((x : Nat) -> f x == g x)
(x : Nat) -> Nat
\forall x : Nat. Nat
∀x : Nat. Nat
ind : ∀b. ∀P. P true -> P false -> P b;
ind : (b : _) -> (P : _) -> P true -> P false -> P b;
x => x
\lambda x. x
λx -> x
Inductive Linear : Context -> Term -> Type :=
| L_var var : Linear [var] (T_var var)
| L_lam {lam_ctx} param
{body_term} (body : Linear (param :: lam_ctx) body_term)
(param_not_free_in_lam_ctx : free_in_ctx param lam_ctx = false)
: Linear lam_ctx (T_lam param body_term)
| L_app {lam_ctx lam_term} (lam : Linear lam_ctx lam_term)
{arg_ctx arg_term} (arg : Linear arg_ctx arg_term)
: Linear (append lam_ctx arg_ctx) (T_app lam_term arg_term)
x ⊢ x
Γ, x ⊢ M -> not (free x Γ) -> Γ ⊢ x. M
Fix n = (Fix 1, (f : Fix 1) -[1]> Unit);
(f : Fix 1) => (
(x, k) = f;
k x;
)
Fix (G + 1) = (x : Fix G) -[1]> Unit;
(x : Fix 1) => (
x x
)
Nat = (G : Grade, (A : Type) -> (1 z : A) -> (G s : A -> A) -> A);
f = (G : Grade) => Int G
T = Int 1;
((A : Type) -> A);
Type 0 : (G : Grade) -> Type 1 G
Γ |- n : Grade Γ |- A : Type
-----------------------------
Γ, x $ n : A
Type : Type $ 0;
Γ |- A : Type Γ |- n : Grade
-----------------------------
Γ |- M : A $ n
Γ, x : A $ n |- B : Type $ 0
------------------------------------
Γ |- ((x : A $ n) -> B $ m) : Type $ 0
Γ, x : A $ n |- M : B $ m
--------------------------------------------------
Γ |- (x : A $ n) => M : ((x : A $ n) -> B $ m) $ k
Γ |- M : ((x : A $ m) -> B $ n) $ 1 Γ |- N : $ n
--------------------------------------------------
Γ |- M N : ((x : A $ n) -> B $ m) $ k
(x : A $ 1) => x : A
Type $ 0 : Type
(x : Socket$) => _;
Id
: (A : Type $ 0) => Type $ 0;
= (A : Type $ 0) => A;
Never = (A : Type) ->
id = (A $ 0 : Type) => (x $ G : A) => x
id = ({A} => (x $ 1 : A) => x) $ 15;
A $ G -> A $ G
id
: (A : Type $ 0) -> (x : A $ 'X) -> (A $ 'X) $ _G
= (A : Type) => (x : A) => x;
(x : Int $ 5) => (
incr () = x + 1;
incr : () -> (Int $ _X) $ _Y where _X * _Y = 5
// but, this seems as powerful
incr : () -> (Int $ 1) $ 5
// and more general than, but maybe this could put it back
incr : () -> (Int $ 5) $ 1
);
Nat = (G : Grade, (A $ 0 : Type) -> ($ 1 : A) -> ($ G : ($ 1 : A) -> A) -> A);
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool $ 0 -> Type $ 0) ->
P true $ @b (_ => Grade) 1 0 ->
P false $ @b (_ => Grade) 0 1 -> P b $ 1;
true = P => x => y => x;
false = P => x => y => y;
dup (b : Bool $ 1) : Bool $ 2 =
b _ true false;
// without Grade : Type
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool $ 0 -> Type $ 0) ->
@b (_ => Type $ 0) (P true $ 1) (P true $ 0) ->
@b (_ => Type $ 0) (P false $ 0) (P false $ 1) -> P b $ 1;
true = P => x => y => x;
false = P => x => y => y;
dup (b : Bool $ 1) : Bool $ 2 =
b _ true false;
// erasable only
Bool : Type;
true : Bool 'G;
false : Bool 'G;
Bool = b @-> (P : Bool $ 0 -> Type $ 0) ->
P true $ @b (_ => Grade) 1 0 ->
P false $ @b (_ => Grade) 0 1 -> P b;
true = P => x => y => x;
false = P => x => y => y;
dup (b : Bool $ 1) : Bool $ 2 =
b _ true false;
//
Unit = (0 A : Type) -> A -> A;
unit : Unit = A => x => x;
Bool_0 = (0 K : Type) -> ((0 A : Type) -> A -> K) -> K;
true : Bool_0 = K => k => k Unit unit;
false : Bool_0 = K => k => k Unit unit;
// closed
Closed A = <G>A $ G;
Bool = (A : Type) -> Closed A -> Closed A -> A;
true : Closed Bool = <G>(A => x => y => (_ = y<0>; x)) $ G;
false : Closed Bool = <G>(A => x => y => (_ = x<0>; y)) $ G;
dup (b : Bool $ 1) : Closed Bool =
b (Closed Bool) true false;
case : (b : Bool_0) -> (A : Type) -> (<G>(A $ G) $ 1) ->
// inductive version
Bool_0 b = (
(G_true, G_false) = b;
(P : Bool_B -> Type) -> P true_b $ G_true -> P false $ G_false -> P b $ 1
);
true_0 : Bool_0 true_b = P => x => y => x;
false_0 : Bool_0 false_b = P => x => y => y;
// church version
Bool_B = (Grade, Grade);
true_b : Bool_B = (1, 0);
false_b : Bool_B = (0, 1);
Bool_0 = (
G_true : Grade, G_false : Grade,
(A : Type) -> A $ G_true -> A $ G_false -> A $ 1
);
true_0 : Bool_0 = (1, 0, A => x => y => x);
false_0 : Bool_0 = (0, 1, A => x => y => x);
//
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool $ 0 -> Type $ 0) ->
@b (_ => Type $ 0) (P true $ 1) (P true $ 0) ->
@b (_ => Type $ 0) (P false $ 0) (P false $ 1) -> P b $ 1;
true = P => x => y => x;
false = P => x => y => y;
dup (b : Bool $ 1) : Bool $ 2 =
b _ true false;
@Bool =
b @->
(P : Bool $ 0 -> Type $ 0) ->
P (b @=> P => (x : P b $ 1) => (y : P b $ 0) => x) $ b (_ => Grade) 1 0 ->
P (b @=> P => (x : _ $ 0) => (y : P b $ 1) => x) $ b (_ => Grade) 0 1 ->
P b $ 1;
true :
dup : ()
expected :
P (b @=> P => (x : P b $ 1) => (y : P b $ 0) => x) $ 1 ->
P (b @=> P => (x : _ $ 0) => (y : P b $ 1) => x) $ 0 ->
P (b @=> P => (x : P b $ 1) => (y : P b $ 0) => x) $ 1
received :
P (b @=> P => (x : P b $ 1) => (y : P b $ 0) => x) $ 1 ->
P (b @=> P => (x : _ $ 0) => (y : P b $ 1) => x) $ 0 ->
P (b @=> P => (x : P b $ 1) => (y : P b $ 0) => x) $ 1
Γ |- n $ 0 : Grade Γ |- A $ 0 : Type
------------------------------------- // Rule
Γ |- t $ n : A $ 0
------------------------- // Type
() |- Type $ 0 : Type
----------------------- // Grade
() |- Grade $ 0 : Type
Γ $ 0 |- A : Type
----------------------------- // Var
Γ $ 0, x $ 1 : A |- x $ 1 : A
Γ |- A $ 0 : Type Γ |- r $ 0 : Grade
Γ, x $ p : A |- B $ 0 : Type
------------------------------------- // Forall
Γ |- (x $ p : A) -(r)> B $ 0 : Type
Γ, x $ p : A |- t $ r : B
-------------------------------------------------- // Lambda
Γ |- (x $ p : A) =(r)> t $ 1 : (x $ p : A) -(r)> B
Γ |- f $ 1 : (x $ p : A) -(r)> B ∆ |- a $ p : A
------------------------------------------------ // Apply
Γ, ∆ |- f a $ r : B[x := a]
Γ |- t $ r : A
---------------------- // Multiply
Γ $ n |- t $ r * n : A
Γ |- f $ 1 : (x $ p : A) -(r)> B ∆ |- a $ p : A
------------------------------------------------ // Apply
Γ, ∆ |- f a $ r : B[x := a]
((x $ 1) =(0)> (x $ 1) x)
(x $ 1) => (
f = (() => x $ 1);
(f () $ 0)
)
f = (() => x) $ 1;
() -> (x $ 0) @=> x
// consumes 4 nat and produces 2 nat
(x $ 4 : Nat) -(2)> Nat
// closed terms can produce G
(G : Grade) =(G)> (x $ 1 : Nat) =(1)> x;
Pat =
| x // var
| P : A // annot
| !P // strict
// TODO: optional
| <P> // implicit
| (P, ...) // tuple
| { P; ... }// module
Term =
| x // var
// TODO: all patterns?
| (x : A) -> B // explicit forall
| <P>B // implicit forall
| P => M // lambda
| M N // explicit apply
| M<N> // implicit apply
// TODO: explain strict, like annot
| !M // strict
// TODO: optional / currying?
| (x : A, ...) // exists
| (P = M, ...) // tuple
| { P : M; ... } // signature
| { P = M; ... } // module
(x : T).a
T::a(x);
(A : Type <: )
(<A>, x) = (a : (<A>, x : A));
<S : Show> =
(b, <P>, x : P true, y : P false) -> P b
∀b. ∀P. P true → P false → P b
(b : _) -> (P : _) -> P true -> P true -> P b
Show = Σ(t : Type, x : T)
// lambda
// apply
M N
// strict apply
!M N
// curried apply
?M N
Fix = (x : FixX) -> ()
FixX = (G : Grade) -> ((x1 : Fix) -> (x : FixX) -> );
fix : Fix = x => (
x
)
(G : Grade) ->
(Grade Kind) GK ::== | + | GK -> GK
(Grade) G, H ::== | g | 0 | 1| λx : GK. G | G H | ∀g. G
(Type) T, U ::== | A | T -> U | ∀A. T | T $ G | ∀g. T
(Term) M, N ::== | x | λx : T. M | M N | ΛA. M | M T | [M $ G] | ΛG. M | M G
(Context) Γ, Δ ::== | • | Γ, x : T | Γ, A | Γ, g
λx : A.
Nat_GK = + -> (+ -> +) -> +;
zero_gk : Nat_GK = λz. λs. z.
succ_gk : Nat_GK -> Nat_GK = λn. λz. λs. s (n z s).
Λg. ΛA. λx : A $ g. x
Λg : Nat_GK. ΛA. λz : A. λs : A $ g. x
∀g . g
(λx : . x) : * -> *
// only weak existentials, can be done through lambdas
Bool === ∃l. ∃r. ∀A. A $ l -> A $ r -> A;
// erasables can be weakened
true : Bool === pack 1. pack 0. λx. λy. x;
false : Bool === pack 0. pack 1. λx. λy. y;
dup : Bool -> (Bool * Bool) === λb.
unpack (l, (r, b)) = b in
// closed terms can satisfy any grade
b (Bool * Bool) [(true, true) $ l] [(false, false) $ r]
Closed A === ∀g. (A $ G);
Nat === ∀A. A -> Closed (A -> A) -> A;
zero : Nat === ΛA. λz. λs. (_ = s 0; z);
one : Nat === ΛA. λz. λs. s 1
Bool === ∀A. Closed A -> Closed A -> A;
// erasables can be weakened
true : Bool === ΛA. λx. λy. (_ = y 0; x);
false : Bool === ΛA. λx. λy. (_ = x 0; y);
dup : Bool -> Closed (Bool * Bool) ===
// closed terms can satisfy any grade
λb. b (Bool * Bool) (Λl. [(true, true) $ l]) (Λr. [(false, false) $ r])
Term =
| Context
| •
| Γ, (x : A)
| M[Γ]
| Type
| x
| ∀(x : A). B
| λ(x : A). M
| M N;
• |- Γ : Context Γ |- A : Type
-------------------------------
Γ |- M : A
----------------
• |- Type : Type
-------------------
• |- Context : Type
----------------
• |- ∅ : Context
Δ |- Γ : Context Γ |- A : Type
-------------------------------
Δ |- Γ, (x : A) : Context
Γ |- Δ : Context Γ ∘ Δ |- M : A
--------------------------------
Γ |- M[Δ] : A
• |- Γ x : A
------------
Γ |- x : A
• |- Γ 0 == A
-------------
Γ |- 0 : A
0 = (x : Type) => x
Γ ((x : Type) => x) == A
((x : Type) => x) A == A
• |- Γ 0 == (x : A) -> B • |- Γ 1 == A
---------------------------------------
Γ |- 0 1 : B[x := A]
• |- Γ 1 == A
-------------
Γ |- 1 : A
Nat = _;
true = x => k => k (x => x) x;
false = x => k => k x ();
weak ctx v = ctx (S v);
xchg ctx v = ctx (S v)
drop ctx =
[1; 2; 3]
[2; 1; 3]
[(λx y k.k x y); 2; 1; 3]
[(λy k.k 2 y); 1; 3]
[(λk.k 2 1); 3]
[3; (λk.k 2 1);]
x => k =>
true = λ(λ0);
false = λλ0;
xchg ctx v =
ctx
| ctx, x =>
(ctx
| ctx, y => Some (ctx, y, x)
| ctx => None)
| ctx => None;
xchg ctx v =
ctx
| ctx, x =>
(ctx
| ctx, y => Some (ctx, y, x)
| ctx => None)
| ctx => None;
apply = x => y => (x y)[xchg];
Nat_0 = Type -> (Type -> Type) -> Type;
one_0 = x => s => s x;
Nat_1 n0 =
Context = (A : Type) -> A -> (Type -> A -> A) -> A;
empty : Context = A => acc => f => acc;
cons T ctx = A => acc => f => f T (ctx acc f);
rev ctx = ctx Context • (A => Γ => A . Γ);
empty = (Type, None);
T | Γ |- Δ : Context Δ |- T : A
--------------------------------
T | Γ |- M[Δ] : A
(T, x : )
apply = (x : Type -> Type) => (y : Type) => (x y)[x => y => k => k y x];
apply = x => (x y)[x => k => k {} x];
ctx 0 = A;
ctx 1 = B;
xchg ctx 1 = ctx 0
xchg ctx 0 = ctx 1
Nat = Type -> (Type -> (Type -> Type) -> Type) -> (Type -> Type) -> Type;
zero = z => s => k => k z;
succ = n => z => s => k => s (r => n )
empty v = None
append ctx A v =
v (Some A) (x => ctx (z => ))
()
(b : Bool) => M[b Context (•, (x : Bool)) (•, (y : Bool))]
// first-class binders?
Term =
| Subst
| [xchg]
| [x : A]
| M[Δ]
| Type
| x
| ∀(x : A). B
| λ(x : A). M
| M N;
Γ |- A : Type
-------------
Γ |- M : A
----------------
• |- Type : Type
-----------------
• |- Subst : Type
--------------
• |- xchg : Subst
Γ |- A : Type
--------------------
Γ |- [x : A] : Subst
--------------
• |- xchg : Subst
Γ |- A : Type
-----------------------
Γ |- M[xchg] : Γ, x : A
Γ |- Δ : Subst Δ Γ |- M : A
-----------------------------
Γ |- M[Δ] : A
// reflections
apply = x => y => (x y)[xchg];
apply = (x y)[y][x]
apply = x[y][x] y[y][x]
(b : Bool) =>
M[b Subst [x : Bool] [y : Bool]][b Subst [y : Bool] [x : Bool]]
M[b Context [x : Bool] [y : Bool]]
b _ ((x : Bool) => M) ((y : Bool) => M)
M[b Context [x : Bool] [x : Int]]
b _ ((x : Bool) => M) ((x : Int) => M)
M[x : A]
Closed A = <G>A $ G;
swap = <A> => (x : A) => (y : A) =>
<K> => (k : A -> A -> K) : K => k y x;
noop = <A> => (x : A) => (y : A) =>
<K> => (k : A -> A -> K) : K => swap y x (x => y => swap x y k);
Bool =
<A> -> Closed A -> Closed A -> Closed A;
true : Closed Bool =
<G> (<A> => x => y => noop y x (x => y => ((_ : A $ 0) => x) (y<0>))) $ G;
false : Closed Bool =
<G> (<A> => x => y => swap y x (y => x => ((_ : A $ 0) => y) (x<0>))) $ G;
dup (b : Bool) : Closed Bool = b Bool true false;
[x; y] |- term
[y; x] |- (y => x => term) y x
[a; b; x; c; d] |- term
[x; a; b; c; d] |-
(c => d => (d => c => x => b => a => term) d c x a b) c d
(d => c => x => b => a => term) d c
(d => c => x => b => a => term)
(c => d => (d => c => x => b => a => term)) x a b c d
x => y => y x
x => y => x y
x => y => (y => x => x y) y x
[x; y] body
x => (y => body)
((f lam a) b) c
f lam a b c
(x => y => k x y)
x ∈ Γ x ∉ Δ
------------
Γ, Δ
------
x |- x
Γ, x |- M
----------
Γ |- λx. M
Γ |- M Δ |- N
--------------
Γ, Δ |- M N
//
------
l |- 0
l |- x
----------------
l + 1 |- (1 + x)
l + 1 |- M
----------
l |- λ.M
l |- M r |- N
--------------
Γ, Δ |- M N
λx.λx.x x
λx.x x
G ::== | g | 0 | S g | ∞
------
1 |- 0
n |- n
--------------
1 + n |- n
1 + Γ |- M
----------
Γ |- λM
Γ |- M Γ + Δ |- N
------------------
Γ + Δ |- M N
λ λ (λ0) 1 2
Γ |- M Δ |- N
--------------
Γ, Δ |- M N
<A>(x : A) => A
(x => M)(N)
M[x := N]
(x => x x) (x => x x)
(x x)[x := x => x x]
(x => x x) (x => x x)
(x => x x)(x => x x)
(x x)[x := x => x x]
(x => x x) (x => x x)
Promise<[A]>
0 0
λ 0 1
M |-
--------------------
M :: N :: [] |- @ :
Γ, x |- M
----------
Γ |- λx. M
Γ |- M Δ |- N
--------------
Γ, Δ |- M N
Term =
| Type
| x
| (x : A) -> B
| (x : A) => M
| M N
| x @-> T
| x @=> M
| @M;
Value =
| Grade
| Type
| x
| (x : A) -> B
| (x : A) => M;
Term =
| ...Value
| M V;
[f => x => m (x => f x)]
f => x => m (f x)
Id = <A>(x : A) -> A;
Bool = <A>(x : A, y : A) -> A;
not : (b : Bool) -> Bool = _;
if : (b : Bool) -> Bool = _;
call_if (if : (b : Bool) -> Bool) b = if b 1 0;
f : (id : <A>(x : A) -> A) -> Int
f id = id 1;
f : (id : (x : Int) -> Int) -> Int
f id = id 1;
left_or_right : String -> String -> String -> String
left_or_right l r = (
b = String.equal l r;
b "abc";
);
left_or_right l r = (
b = String.equal l r;
b (y => "abc") (y => y);
)
b := (b_ptr, 0, null, null)
b := (b_ptr, 1, x, null)
rec@fold f acc n =
n
| 0 => acc
| S p => fold f (f acc) p;
mul = n => m => fold (acc => add acc m) 0 n;
mul = n => m =>
(rec fold f acc n =>
n
| 0 => acc
| S p => fold f (add acc m) p
) 0 n;
TypeScript / Rust ->
Java / C / C++ / OCaml ->
Python / Go / Clojure / Elixir ->
Swift / Haskell / PHP / Ruby
Rust is affine / linear
Rust uses result for everything
TypeScript IO is fully tracked
const id = (x : Nat) => x;
const id = <A>(x : A) => x;
type Id<A> = A;
type T<B> = B extends true ? number : string;
id = (x : Nat) => x;
id = (A : Type) => (x : A) => x;
Id = (A : Type) => A;
T = (B : Bool) => b | true => Nat | false => String;
module type S = sig
type t
val x : t
end
type t = { x : int; }
type fcm = (module S)
type 'a obj = object val x : int end as 'a
S = {
T : Type;
x : T
};
t = { x : Int; };
fcm = S;
obj = R => ({ x : Int; ...R; })
if_b_then_int_else_string
: (b : Bool) -> (x : b | true => Int | false => String) => b | true => Int | false => String
= (b : Bool) => (x : b | true => Int | false => String) => x;
if_b_then_int_else_string = <A extends bool>(b : A extends true ? number : string, x : A) => x
f = (s : String & JSON.is_valid s == true) => s;
Color =
| Red
| Green
| Blue;
f = (color : Color & color != Red) => _;
make = (n : Int & n >= 0 || n == -1) => n;
id = (A : Type) => (x : A) => (
() = console.log(x);
x
);
incr = (x : id Type Int) => x + 1;
incr = (x : Int) => x + 1;
main : IO ()
main = print "Hello World"
print : World -> String -> World;
main : World -> World
main world0 = (
world1 = print world0 "Hello World";
world2 = print world0 "Wrong";
world2
)
Socket : {
send : (sock : Socket, msg : String) -> Socket;
close : (sock : Socket) -> ();
};
f = (s : Socket) -> (
s1 = send(s, "a");
close(s1);
)
double = (x : Nat $ 2) => x + x;
double = x => x + x;
id = (A : Type $ 0) => (x : A $ 1) => x;
dup = (x : Nat $ 2) => (x : Nat, x : Nat);
CoC
+ Self Types
+ Graded
+ Inference
read = (file : String) -> Eff [Read] (String);
read "hello.txt"
id = (x : Nat) => (
() = @debug(x);
x + 1
);
() = Fuzz.nat(x => x == id x);
Nat => number | bigint
Int => number | bigint
Int32 => number | 0
Int64 => [number, number] | bigint
id = (A : Type) => (x : A) => x
x = id 1;
y = id "a";
x = id 1;
y = id "a";
call_id = (id : (A : Type) -> (x : A) -> A) => id(1);
data@Option<A> =
| Some(content : A)
| None;
apply = x => y => (y => x => x y) x y;
ML = f -> f
read : (world : World, file : String) -> Result (World, String) Error;
read : (world : World, file : String) -[Error]> (World, String);
read : (file : String) -[IO]> String;
main : () -[IO]> ()
main () = (
file = read("tuturu.txt");
print(file);
);
List.map (x =>
x.? > 0
| true => Ok (x + 1)
| false => Error "bad"
)
List.map (x =>
x > 0
| true => x + 1
| false => throw (Error "bad")
)
main : Eff [IO; Error] ()
main : World -> World
main world = (
file = read("tuturu.txt");
print(file);
);
Term =
| Type
| (x : A) -> B
| (x : A) => M
| M N
| x @-> T
| x @=> M
| @M;
Term =
| Type
| (x : A $ G) -> B
| (x : A $ G) => M
| M N
| x @-> T
| x @=> M
| @M;
Unit = Unit @=> I =>
u @-> (P : (u : Unit) -> Type) -> (x : I P (u @=> P => x => x)) -> I P u;
Fix = (x : Fix $ 0) -> Type;
f = ((x : Fix $ 0) => x x);
f = ((x : Fix $ 0) => x x);
False = False @=> f @->
(P : ((f : False $ 0) -> Type) $ 0) -> P
(x : @f f) => _;
False = False @=>
f @-> (P : ((f : False $ 0) -> Type) $ 0) -> P f
Γ |- M : (x : A $ n) -> B $ 1 Δ |- N : A $ n
---------------------------------------------
Γ, Δ |- M N $ 1
Fix = (x : Fix $ 1) -> Type;
T : (T $ 0, 1) @-> Type = T @=> @T;
x = (A : Type $ 0, 2) -> Type;
y = (A : Type $ 0, 2) => (x : A) -> A;
y = (A : Type $ 0, 2) => (x : A) -> A;
T : (T $ 0, 1) @-> (A : Type) -> Type = T @=> @T;
@(T @=> @T) === @(T @=> @T)
False = (False : Type $ 0) @=>
f @-> (P : ((f : False $ 0) -> Type) $ 0) -> P f
T_x : (f $ 0, 1) @-(0)> (A : Type) -> A;
f : T_x = f @=> @f;
x = @f : (A : Type) -> A $ 0;
Fix = (x $ 0, 0 : Fix) -(0, 0)> ();
fix : Fix = (x $ 0, 0 : Fix) =(0, 0)> x x;
Fix = (x : Fix $ 0, 0) -> ();
Id = (A : Type $ 0) =(0)> A;
((x : Id Nat) => x);
False @-(0)> Type;
Unit = Unit @=(1)> I =>
u @-(1)> (P $ 2 : (u $ 1 : @Unit I) -> Type) -(1)>
(unit $ 1 : I P (u @=> P => x => x)) -(1)> I P u;
T_False = False @-(2)> (f $ 1 : f @-(1)> @False f) -(1)> Type;
False $ _G : T_False = False @=(2)> f =>
(P : (G : Grade) (f $ 1 : f @-(1)> @False f) -> Type) -(1)> P f;
T_Unit = Unit @-(_)>
(I : I @-> ) -(1)> Type;
Unit : T_Unit = Unit @=(_)> I =>
u @-(_)> (P $ 2 : _) -(_)> ();
False = f @-(1)> @False f;
@(F @=(2)> (P $ 4) => (@F P, @F P));
F = F @=(1, 0)> @F
@(False @=(2)> (f $ 1 : f @-(1)> @False f) =>
(P $ 1 : (f $ 1 : f @-(1)> @False f) -> Type) -(1)> P f)
(f $ 1 : f @-(1)> @False f) =>
(P $ 1 : (f $ 1 : f @-(1)> @False f) -> Type) -(1)> P f
False = False @=(n)>
f -(1)> (P $ 1 : (f $ 1 :) -> Type) -(1)>
(A $ 2 : Type) -> (x $ 1 : A) -> A
Fix = (x $ 2 : @Fix) -(0)> ();
fix = (x $ 2 : @Fix) =(0)> x x;
T_F = F @-(1)> (A : Type) -> Type;
F = F @=(1)> @F;
@(F @=(1)> @F);
Unit = Unit @=(1, 0)>
u @-(1, 0)> (P $ (2, 0) : (u $ (1, 0) : Unit) -> Type) ->
P (u @=(1, 0)>
(P $ (2, 0) : (u $ (1, 0) : Unit) -> Type) =>
(x : P u) => x
) -> P u;
fix = (x : Fix $ 0, 0) =(0)>
(A : Type $ 2, 0) -> (x : A $ 0, 1) -> A;
()
(A : Type) => (B : ) => (x : A) =>
Term =
| Type
| x
| (x : A) -> B
| (x : A) => M
| M N;
(A : Type) -> A;
Context = List Type;
-------------
Γ |- A : Type
Ind (T : Type) =
(P : Type -> Type) ->
P Type ->
((A : Type) -> (B : (x : A) -> Type) ->
P A -> (x : A) -> P (B x) -> P ((x : A) -> B x)) ->
P T;
x : Ind Type = P => p_type => p_forall => p_type;
T_Id = (A : Type) -> Type;
T_Id_ind : Ind T_Id = P => p_type => p_forall =>
p_forall Type Type p_type p_type;
(A : Type) : Ind A = P => p_type => p_var => p_var A;
x => (A : Type) => (B : Type) => _
Dyn =
(A : Type, x : A);
Ind {A} (T : A) =
| Univ : Ind Type;
| Forall
A (a_dyn : Ind A)
B (b_dyn : (x : A) -> Ind (B x))
: Dyn ((x : A) -> B x);
| Lambda
A (a_dyn : Ind A)
B (b_dyn : (x : A) -> Ind (B x))
M (m_dyn : (x : A) -> Ind (M x))
: Dyn ((x : A) => (M x : B x));
Dyn = (A : Type, T : A, ind : Ind T);
False @-(0)> (f : f @-(0)> False f) -> Type;
----------------------
Γ |- x @-(0)> T : Type
----------------------------
Γ |- x @=(0)> M : x @-(0)> T
Γ, x : x @-(l)> T : T |- Type
-----------------------------
Γ |- x @-(1 + l)> T : Type
Γ, x : x @-(l)> T : T |- Type
-----------------------------
Γ |- x @-(d)> T : Type
(w : Type $ ω) -> 1
Γ, x : x @-(l)> T : T |- Type
-----------------------------
Γ |- (d, False) : Type $ ω
(d, False) @-> (f : (d, f) @-> @False d f) -> Type;
Γ, x : x @-(l)> T : M |- T[x := x @=(l)> M]
-------------------------------------------
Γ |- x @=(1 + l)> M : x @-(1 + l)> T
----------------------
Γ |- x @=(0)> M : x @-(l)
-------------------
Γ |- x @-> T : Type
False = False @=>
f @-> (P : @False -> Type) -> P f;
Γ, x : x @-(l)> T : T |- Type
-----------------------------
Γ |- x @-(l)> T : Type
Term =
| Grade
| Type
| (x : A) -> B
| (x : A) => M
| M N;
Type : Type $ 0
(x : A, y)
Type $ 2
(x : ?)
Type : Type $ 0
Unit = Unit @=> (G : Grade) ->
u @-(G)> (P : @Unit -> Type) -> P (u @=(G)> P => x => x) -> P u;
x @-(G)> ()
(x : ((G : Grade) -(G)> Nat) $ 1)
(x : ((G : Grade) -(G)> Nat G) $ 1)
(G : Grade) ->
Γ |- A : Type $ n Γ |- B : Type $ 1
-------------------------------------
Γ |- (x : A) -> B :
Γ |- x :
-------------------------------------
Γ |- x @-> T :
False @-> (f : f @-> @False f) -> Type;
False_C = (A : Type) -> A;
False_0 = (f_c : False_C, i : (P : False_C -> Type) -> P f_c);
False_1 = (f_0 : False_0, i : (P : False_0 -> Type) -> P f_0);
False_2 = (f_1 : False_1, i : (P : False_1 -> Type) -> P f_1);
Γ, x : x @-> (G : Grade) -> T, G : Grade |- T : Type $ G
--------------------------------------------------------
Γ |- x @-> (G : Grade) -> T :
Γ, x : x @-> (G : Grade) -> T, G : Grade |- T : Type $ G
--------------------------------------------------------
Γ |- x @-> (G : Grade) -> T : Type $ ω
False @-> (G : Grade) -> (f : f @-> (G : Grade) -> @False G f) -> Type;
False @-(1)> (f : f @-(1)> @False f) -> Type;
False = (G, False) @=> ((G, f) @-> (P : @False G -> Type) -> P f) G;
@False 0 === Base
@False 1 === f @-> (P : @False 0 -> Type) -> P f
T_False = False @-> (f : f @-> @False f) -> Type;
T_False_C = Type;
T_False_0 = (f : False_C) -> Type;
@False == f @-(1)>
(P : @(False @=(0)> f @-(1)> (P : @False -> Type) -> P f) -> Type) ->
P f
False_0 f_c = (P : False_C -> Type) -> P f_c;
False_1 f_0 = (P : False_C -> Type) -> P f_0;
Bool_C = (A : Type) -> A -> A -> A;
true_c : Bool_C = A => x => y => x;
false_c : Bool_C = A => x => y => y;
Bool_0 b_c = (P : Bool_C -> Type) -> P true_c -> P false_c -> P b_c;
Γ |- M[G := 0][x := (G, x) @=> M] : T[G := 0][x := (G, x) @=> M]
Γ |- M[G := 0][x := (G, x) @=> M] : T[G := 0][x := (G, x) @=> M]
----------------------------------------------------------------
Γ |- (G, x) @=> M : (G, x) @-> T
(G, False) @=> (G, f) @-> (P : False@G -> Type) -> P f;
(G, f) @-> (P : False@G -> Type) -> P f
(G, f) @-> (P : ((G, f) @-> (P : False@G -> Type) -> P f) -> Type) -> P f;
f @-(G)> (
b : (A : Type) -> A,
i : (P : False@G -> Type) -> P f
);
f @-(0)> (
b : (A : Type) -> A,
i : (P : False@G -> Type) -> P f
) === (A : Type) -> A
f @-(1)> (
b : (A : Type) -> A,
i : (P : False@G -> Type) -> P f
) === (P : False@G -> Type) -> P f
f @-> (P : False@G -> Type) -> P f
Γ, x : x @-(G)> T |- T : Type
-----------------------------
Γ |- x @-(1 + G)> T : Type
False @-(0)> (f : f @-(1)> @False f) -> Type
Γ, x : x @-(G)> T |- T : Type
-----------------------------
Γ |- x @-(1 + G)> T : Type
Unit @=(1)> u @-> (P : @Unit -> Type) ->
P (u @=> P => x => x) -> P u;
Γ, x : x @-(G)> T |- T : Type
-----------------------------
Γ |- x @-(1 + G)> T : Type
Γ |- M : x @-(0)> T
------------------------- // Lower Base
Γ |- lower M : Unit
Γ |- M : x @-(1 + G)> T
------------------------- // Lower Succ
Γ |- lower M : x @-(G)> T
------------------------------------------ // Lower Base Compute
Γ |- lower (x @=(0)> M) === unit
------------------------------------------ // Lower Succ Compute
Γ |- lower (x @=(1 + G)> M) === x @=(G)> M
Γ |- M[x := lower M] : T[x := lower M]
-------------------------------------- // Fix Succ
Γ |- x @=(G)> M : x @-(G)> T
Γ |- M : x @-(0)> T
---------------------- // Unroll
Γ |- @M : T[x := unit]
Γ |- M : x @-(G)> T
------------------------- // Unroll Typing
Γ |- @M : T[x := lower M]
Γ |- M : x @-(G)> T
------------------------- // Unroll Compute
Γ |- @M : T[x := lower M]
// extensions
Γ, x : lower (x @-(G)> T) |- M : T[x := lower M]
------------------------------------------------ // Fix Weak
Γ |- x @=(G)> M : x @-(G)> T
Γ |- M : (x $ n) @-> T $ 1 + n
------------------------------ // Unroll
Γ |- @M : T[x := M] $ 1
Γ |- M : (x $ n) @-> T $ 1 + n
--------------------------------------------- // Unroll Compute
Γ |- @((x $ n) @=> M) : M[x := (x $ n) @=> M]
Γ, x : (x $ n) @-> T |- M : T[x := (x $ n) @=> M]
-------------------------------------------------
Γ |- (x $ n) @=> M : (x $ n) @-> T
(False $ 1) @-> Type;
(False $ 0) @=> (A : Type) -> A;
(False $ 1 + G) @=> f @-> (P : @False -> Type) -> P f;
(False $ 1) @=> f @-> (P : @False -> Type) -> P f
(False $ 1) @=> f @-> (P : @False -> Type) -> P f;
case : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = (P : Bool -> Type) -> P true -> P false -> P b;
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Γ, x : x @-> T |- T : Type
-------------------------- // Self
Γ |- x @-> T : Type
Γ, x : x @-> T |- M : T[x := x @=> M]
------------------------------------- // Fix
Γ |- x @=> M : x @-> T
(x $ 2) => x + x
x0 => x1 => x0 + x1
(x => x x) (x => x x)
Either A B =
| Left (content : A)
| Right (content : B);
Either A B =
(tag : Bool, content : tag Type A B);
(either : Either Int String) => (
(tag, content : tag Type Int String) = either;
ind tag (b => (b Type Int String) -> String)
(content => Int.to_string content) (content => content) content
)
(False $ 0) @=> (A : Type) -> A;
(False $ 1 + G) @=> f @-> (P : @False -> Type) -> P f;
(Loop $ 0) @=> Unit
(Loop $ 1) @=> () -> @Loop
(Loop $ 1) @-> Type;
(Loop $ 2) @=> () -> @Loop;
@((Loop $ 2) @=> () -> @Loop)
(Loop $ 2) @=> () -> () -> Unit;
(Loop $ 2) @=> () -> @((Loop $ 1) @=> () -> @Loop)
Γ |- T : Type // try ((x $ 0) @-> T) $ 0
--------------------------------------------- // Fix Succ
Γ |- (x $ 0) @-> T : (x $ 0) @-> T
Γ, x : (x $ G) @-> T |- T : Type
--------------------------------------------- // Fix Succ
Γ |- (x $ 1 + G) @-> M : (x $ 1 + G) @-> T
Γ |- M : T // try ((x $ 0) @=> M) $ 0
------------------------------------- // Fix Base
Γ |- (x $ 0) @=> M : (x $ 0) @-> T
Γ, x : (x $ G) @-> T |- M : T[(x $ G) @=> M]
--------------------------------------------- // Fix Succ
Γ |- (x $ 1 + G) @=> M : (x $ 1 + G) @-> T
Γ, x : (x $ G) @-> T |- T : Type
-------------------------------- // Self Succ
Γ |- (x $ 1 + G) @-> T : Type
False : Type $ 0
(False $ 0) @=> Unit;
(False $ 1) @=> (f $ 1) @-> (P : @False -> Type) -> P f;
(False $ 2) @=> (f $ 1) @-> (P : @False -> Type) -> P f
False @-> (f : f @-> @False f) -> Type;
Γ |- Z : Type
------------------------------ // Self Base
Γ |- @self(0, Z). S : Type $ 0
Γ, x : @self(G, Z). S |- S : Type
-------------------------------------- // Self Succ
Γ |- @self(1 + G, Z). S : Type $ 1 + G
@self(0, Type).
(f : @self(1, ). f @-> @False f)) -> Type;
@fix(
(A : Type) -> Type,
False =>
);
∀G. T [G]
(G : Grade)
zero = z => z;
one = s1 => z => s1 z;
two = s2 => s1 => z => s2 (s1 z);
three = s3 => s1 => z => s3 (s2 (s1 z));
let Closed A = ∀(G : Grade). A [G]
// closed as it is unknown how many copies it will be needed(0..1)
let Bool : Type = ∀(A : Type). Closed A -> Closed A -> Closed A
let true : Closed Bool =
// safe to ignore y as it is used 0 times
ΛG. [ΛA. fun x y -> let [y] = y 0 in x]
let false : Closed Bool =
ΛG. [ΛA. fun x y -> let [y] = x 0 in y]
// same applies to nats but (0..n)
let Nat : Type = ∀(A : Type). Closed A -> Closed (A -> A) -> Closed A;
let zero : Closed Nat =
ΛG. [ΛA. fun z s -> let [s] = s 0 in z];
let one : Closed Nat =
ΛG. [ΛA. fun z s -> let [s] = s 1 in s z];
let two : Closed Nat =
ΛG. [ΛA. fun z s -> let [s] = s 2 in s (s z)];
False @-> (f : f @-> @False f) -> Type;
T_False_0 = Type;
T_False_1 (False_0 : T_False_0) = (f_0 : False_0) -> Type;
T_False_2 (False_0 : T_False_0) (False_1 : T_False_1 False_0) =
(f_0 : False_0) -> (f : False_1 f_0) -> Type;
False_0 = (A : Type) -> A;
False_1 (f_0 : False_0) = (P : False_0 -> Type) -> P f_0;
False_2 (f_0 : False_0) (f_1 : False_1 f_0) =
(P : (f_0 : False_0) -> False_1 f_0 -> Type) -> P f_0 f_1;
False_0 = (A : Type) -> A;
False_1 (f_0 : False_0) = (P : False_0 -> Type) -> P f_0;
False_2 (f_0 : False_0) (f_1 : False_1 f_0) =
(P : (f_0 : False_0) -> False_1 f_0 -> Type) -> P f_0 f_1;
// something like the following
False n = (P : n Type Type _) -> n Type P _;
False_1 = @fix(2,
(A : Type) -> A,
False. (f : False) => (P : False -> Type) -> P f
);
False_1 = @fix(G,
(A : Type) -> A,
G -> False -> @self(G, False,
G -> f -> (P : False G -> Type) -> P f)
);
False G = @fix(G,
(A : Type) -> A,
G -> False -> @self(G, False,
G -> f -> (P : False G -> Type) -> P f)
);
False = @fix(1,
(A : Type) -> A,
G -> False -> @self(1 + G, False,
G -> f -> (P : False G -> Type) -> P f)
);
False = @self(1, (A : Type) -> A,
G -> f -> (P : False G -> Type) -> P f)
Unit = @fix(1,
(A : Type) -> A -> A,
G -> Unit -> @self(1 + G, Unit,
G -> u -> (P : Unit G -> Type) -> P unit -> P u)
);
Unit =
@self(1, (A : Type) -> A -> A,
G -> u -> (P : Unit G -> Type) -> P unit -> P u)
unit = @fix(1, A => x => x,
G -> u -> P => x => x);
T_False G = @self(G, G => False => (f : False G) -> Type);
False G = @fix(G, G => False => (f : False G) => (P : False G -> Type) -> P f);
T_False G = @self(G, G => False => (f : False G) -> Type);
T_False_1 = @self(1, Type, False. (f : False) -> Type);
False_1 = @fix(1, (A : Type) -> A, False. f => (P : False -> Type) -> P f);
T_Unit_1 = @self(1, Type, Unit. (f : False) -> Type);
@self(1, Type, False. (f : False) -> Type);
Γ |- Z : Type
--------------------------------- // Self Base
Γ |- @self(0, Z, x. S) : Type $ 0
Γ, x : @self(G, Z). S |- S : Type
----------------------------------------- // Self Succ
Γ |- @self(1 + G, Z, x. S) : Type $ 1 + G
@self(1, Type, False. (f : False) -> Type);
@fix(False, f) @=> (P : False -> Type) -> P
@self(0, Type),
False @-> (f : False )
@self(1, Type, G => False => (f : False G) -> Type)
Unit = (P : W Type) -> I P -> S P;
Term =
| Grade
| Type
| (x : A $ n) -(m)> B
| (x : A $ n) =(m)> M
| M N;
case : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b;
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
(b : Bool) => @b : (P : Bool -> Type) -> P true -> P false -> P b
Γ, x : x @-> T |- T : Type
--------------------------
Γ |- x @-> T : Type
Γ |- M : x @-> T
-------------------
Γ |- @M : T[x := M]
False @-> (f : f @-> False f) -> Type;
Γ |- G : Grade Γ |- Z : Type
Γ, G : Grade, False : @self(G, Z, G => False => S) |- S : Type
--------------------------------------------------------------
Γ |- @self(G, Z, G => False => S) : Type
Γ |- Z : Type
--------------------------------------------
Γ |- @self(0, Z, G => False => S) : Type
Γ, False : @self(d, Z, G => False => S) |- S[G := d] : Type
-----------------------------------------------------------
Γ |- @self(1 + d, Z, G => False => S) : Type
@self(0, Type, G => False =>
(f : @self(G, False_B, G => f => False G f)) -> Type);
@self(1, Type, G => False =>
(f : @self(G, False_B, G => f => False G f)) -> Type);
(False : ) =>
(f : @self(1, False_B, G => f => False G f)) -> Type
@self(2, Type, G => False =>
(f : @self(G, False_B, G => f => False G f)) -> Type);
@fix(G, False_B, G => False =>
f => (P : False G f -> Type) -> P f)
@self(0, Type, G => False => Type);
@fix(1, False_B, G => False =>
@self(G, False_B, G => f => (P : False@G -> Type) -> P f))
False = @fix(False_B, G => False =>
@self(False_B, G => f => (P : False@G -> Type) -> P f)@G);
False_0 = False@0;
False_0 = False_B;
False_1 = @self(False_B, G => f => (P : False@G -> Type) -> P f)@1;
Unit_B = (A : Type) -> A -> A;
unit_b : Unit_B = A => x => x;
Unit G = @fix(Unit_B, G => Unit =>
@self(Unit_B, G => u => (P : Unit@G -> Type) ->
P (@fix(unit_b, G => u => P => x => x)@G) -> P u)@G)@G;
Unit_0 = Unit_B;
unit_0 = unit_b;
Unit_1 = @self(Unit_B, G => u => (P : Unit@G -> Type) ->
P (@fix(unit_b, G => u => P => x => x)@G) -> P u)@1;
unit_1 : Unit_1 =
@fix(unit_b, G => u => P => (x : P u) => x)@1;
@unit_1 :
(P : Unit@0 -> Type) ->
P (@fix(unit_b, G => u => P => x => x)@0) -> P (lower unit_1);
Γ |- Z : Type
--------------------------------------------
Γ |- @self(0, Z, G => False => S) : Type
Γ, False : @self(d, Z, G => False => S) |- S[G := d] : Type
-----------------------------------------------------------
Γ |- @self(1 + d, G => False => S) : Type
@self(1, False_B, G => f => (P : False@G -> Type) -> P f)
Γ |- Z : Type
--------------------------------------------
Γ |- @self(0, Z, G => False => S) : Type
f => (P : False 0 f -> Type) -> P f
@fix(1, False_B, G => False =>
f => (P : False G f -> Type) -> P f)
f => (P : () G f -> Type) -> P f
False_B = (A : Type) -> A;
T_False G = @self(G, Type, G => False =>
(f : @self(G, False_B, G => f => False G f)) -> Type);
False G = @fix(G, False_B, G => False => f =>
(P : @self(G, False_B, G => f => False G f) -> Type) -> P f);
: @self(G, Type, G => False => (f : False G) -> Type)
= @fix(G, False_B, G => False => );
: @self(G, Type, G => False => _)
= @fix(G, (A : Type) -> A, False => _)
T_False_0 = Type;
T_False_1 (False_0 : T_False_0) = (f_0 : False_0) -> Type;
T_False_2 (False_0 : T_False_0) (False_1 : T_False_1 False_0) =
(f_0 : False_0) -> (f : False_1 f_0) -> Type;
False_0 = (A : Type) -> A;
False_1 (f_0 : False_0) = (P : False_0 -> Type) -> P f_0;
False_2 (f_0 : False_0) (f_1 : False_1 f_0) =
(P : (f_0 : False_0) -> False_1 f_0 -> Type) -> P f_0 f_1;
Γ |- G : Grade Γ |- A : Type
Γ, g : Grade, x : @self.lower(@self(G, A, g => x => B))
|- B : Type
-------------------------------------------------------
Γ |- @self(G, A, g => x => B) : Type
Γ |- M : A
Γ, g : Grade, x : @self.lower(@self(G, A, g => x => B))
|- N : B[x := @fix.lower(@fix(G, M, g => x => N))]
-------------------------------------------------------
Γ |- @fix(G, M, g => x => N) : @self(G, A, g => x => B)
Γ |- M : @self(G, A, g => x => B)
---------------------------------
Γ |- @M : B[x := @fix.lower(M)]
Γ |- G : Grade
Γ, g : Grade, x : @self.lower(G, g => x => T) |- T : Type
---------------------------------------------------------
Γ |- @self(G, g => x => T) : Type
Γ, g : Grade, x : @self.lower(G, g => x => T)
|- M : T[x := @fix.lower(@fix(G, g => x => M))]
----------------------------------------------------
Γ |- @fix(G, g => x => M) : @self(G, g => x => T)
Γ |- M : @self(G, g => x => T)
-------------------------------
Γ |- @M : T[x := @fix.lower(M)]
False @-> (f : f @-> @False f) -> Type;
@self(G, G => False => (f : @self(G, G => f => G@False f)) -> Type);
(False : @self(0, G => False => (f : @self(G, G => f => G@False f)) -> Type)) =>
(f : @self(0, G => f => G@False f)) -> Type;
(False : Unit) => (f : Unit) -> Type
@self(0, G => False => (f : @self(G, G => f => G@False f)) -> Type)
@self(1, G => False => (f : @self(G, G => f => G@False f)) -> Type)
T_False G = @self(G, G => False => (f : @self(G, G => f => G@False f)) -> Type);
False : @self.lower(G, G => False => (f : @self(G, G => f => G@False f)) -> Type);
f : @self.lower(G, G => f => G@False f)
False G = @fix(G, G => False => f =>
(P : (f : @self(G, G => f => G@False f))) -> P f);
T = (A : Type $ 0) -> A -> A;
T = (A : Type $ (2, 0)) -> A -> A;
T = (A : Type $ (2, 1)) -> A -> A;
Fix = Fix @=> (x : Fix $ 0) -(0)> (A : Type) -> A;
TFix = Fix @-> Type;
Fix = Fix @=> (x : Fix $ 0) -(0)> (A : Type) -> A
(x : Fix $ (0, 0)) =(0)> x x;
fix : Fix = x => x x;
x : False $ 0 = fix fix;
sock = (socket : Socket$) => ();
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
not : Bool -> Bool = b => b Bool false true;
Eq A x y = (P : A -> Type) -> P x -> P y;
refl A x : Eq A x x = P => x => x;
make = (l : Int & l >= 0) => _;
id
: <A : Type>(x : A) -> A
= <A : Type> => (x : A) => x;
id_string : (x : String) -> String = id<String>;
1 >= 0
| Some one_gte_zero => make (1 & one_gte_zero)
| None
true_eq_true : Eq Bool true true = refl _ _;
true_eq_not_false : Eq Bool true (not false) = refl _ _;
true_eq_not_true : Eq Bool true (not true) = refl _ _;
b_neq_not_b : Eq Bool true (not false) = _;
if_pred_then_string_else_int
: (pred : Bool) -> (x : pred Type Int String) -> pred Type Int String
= (pred : Bool) => (x : pred Type Int String) => x;
f : (x : Int) -> Int
= if_pred_then_string_else_int true
g : (x : String) -> String
= if_pred_then_string_else_int false
Fix = Fix @=> (x : Fix $ (1, 0)) -(0)> (A : Type) -> A
(x : Fix $ (1, 0)) =(0)> x x;
(x : Fix $ 0) -> x x
(f : False $ 0) => (x : P f) =>
---------------
: t : A $ 0
Fix = Fix @=> (x : Fix $ (1, 0)) -(0)> (A : Type) -> A
(x : Fix $ (1, 0)) =(0)> x x;
False = (False $ (2, 0)) @=(0)> (f : (f $ (1, 0)) @-> @False f) =>
(P : (f $ (1, 0)) @-> @False f) -> P f;
False = (False $ (2, 0)) @=(0)> (f : (f $ (_, 0)) @-> @False f) =>
(P : (f $ (_, 0)) @-> @False f) -> P f;
T_T = (T $ (1, 0)) @=(0)> (A : Type) -> A;
T : T_T = T @=> @T;
Type : Type
A : Type 0 = Int;
A : Type 1 = Type 0;
Type n : Type (n + 1)
double = (x : Nat $ 2) => x + x;
double = x => x + x;
case : (b : Bool) -> (P : Bool -> Type) ->
P true -> P false -> P b;
b
| true => ()
| false => ();
("a" : Dyn)
if "a" then 1 else 2
x : Int = 1;
false : (A : Type) -> A = _;
id : (A : Type) -> A -> A = _;
incr : Int -> Int = _;
incr_x_is_plus_one : (x : Nat) -> incr x == x + 1 = _;
may_loop_forever : Int ->! Int = _;
double = (x : Nat $ 2) => x + x;
quadruple = x => double (double x);
false : ((A : Type) -> A) $ 0 = _;
b
| true => ()
| false => ();
case : (b : Bool) -> (P : Bool -> Type) ->
P true -> P false -> P b;
Not (T) = (A <: T) -> A;
Theta = (A <: Top) -> Not ((B <: A) -> Not B);
f = (A0 <: Theta) => (A0 <: (A1 <: A0) -> Not A1);
Not T = (A <: T) -> A;
Theta = (A <: Top) -> Not ((B <: A) -> Not B);
f = (A0 <: Theta) => (A0 <: (A1 <: A0) -> Not A1);
(A : *) => (x : A) => x;
double = (x $ (0, 2)) => x + x;n
Not T = (A <: T) -> A;
Theta = (A <: Top) -> Not ((B <: A) -> Not B);
f = (A0 <: Theta) => (A0 <: (A1 <: A0) -> Not A1);
context = [A0 <: Theta];
received :: A0;
expected :: (A1 <: A0) -> Not A1;
context = [A0 <: Theta];
received :: (A1 <: Top) -> Not ((A2 <: A1) -> Not A2);
expected :: (A1 <: A0) -> Not A1;
context = [A0 <: Theta; A1 <: A0];
received :: Not ((A2 <: A1) -> Not A2);
expected :: Not A1;
context = [A0 <: Theta; A1 <: A0];
received :: (A2 <: Top) -> Not ((A3 <: A2) -> Not A3);
expected :: (A2 <: A1) -> Not A2;
Type : Type
Term =
| Var (x : String)
| Lam (body : Term -> Term);
Ind (A : Type) (x : A) =
| Univ : Ind Type Type
| Forall
A (A_dyn : Ind Type A)
B (B_dyn : (x : A) -> Ind A x -> Ind Type (B x))
: Ind Type ((x : A) -> B x)
| Lambda
A (A_dyn : Ind Type A)
B (B_dyn : (x : A) -> Ind A x -> Ind Type (B x))
M (M_dyn : (x : A) -> Ind A x -> Ind (B x) (M x))
: Ind ((x : A) -> B x) ((x : A) => M x);
Dyn = (A : Type, x : A, Ind A x)
uip : (A : Type) -> (x : A) -> (a : x == x) -> a == refl = _;
Impredicative Universe + Negative Recursin + Subtyping = _;
(b : Bool $ 1 ~ 2) -> (P : Bool $ 0 ~ 2 -> Type) ->
P true $ 1 ~ 0 -> P false $ 1 ~ 0 -> P b;
(x : Nat $ 0 ~ 2) -(0)> Nat;
((x $ 0 ~ 2) =(0)> x + x)
((x $ 2 ~ 2) => x + x)
id : 'A -> 'A = x => x;
id : <A>(x : A) -> A = x =>
T = Int $ 1 ~ 0;
(x : A $ n ~ m) =($ 0 ~ 0)> x
Fix = (x : Fix $ 0 ~ 0) -(0)> (A : False) -> A;
fix = (x : Fix $ 0 ~ 0) =(0)> x x;
false : ((A : False) -> A) $ 0 = fix fix;
Fix = (x : Fix) -> (A : False) -> A;
fix : Fix = x => x x;
Γ |- M : (x $ n ~ m) @-> T $ 1 + n ~ 1 + m
------------------------------------------
Γ |- @M $ 1 ~ ?
(F $ n ~ m) @=> @F
T_False G = @self(G, G => False => (f : @self(G, G => f => G@False f)) -> Type);
False : @self.lower(G, G => False => (f : @self(G, G => f => G@False f)) -> Type);
f : @self.lower(G, G => f => G@False f)
False G = @fix(G, G => False => f =>
(P : (f : @self(G, G => f => G@False f))) -> P f);
False = False @=> f @-(1)> (P : False -> Type) -> P f;
False @-(0)> Type;
False = (False $ 0 ~ 1) @=(0)> (f $ 0 ~ 1) @-(1)>
(P : False $ 0 ~ 1 -(0)> Type) -> P f;
Unit = (Unit $ 0 ~ ) @=(0)> (u $ 0 ~ 1) @-(1)>
(P : Unit $ 0 ~ 1 -(0)> Type) -> P unit -> P u;
False = (False $ 0 ~ 1) @=(0)> (f $ 0 ~ 1) @-(1)>
(P : False $ 0 ~ 1 -(0)> Type) -> P f;
(F $ 0 ~ 1) @=(0)> @F
False = (False $ 0 ~ 1) @=(0)> (f $ 0 ~ 1) @-(1)>
(P : False $ 0 ~ 1 -(0)> Type) -> P f;
T = (f $ 0 ~ 1) @-> (P : False $ 0 ~ 1 -> Type) -> P f;
T = (u $ 0 ~ 1) @->
(P : @Unit $ 0 ~ 1 -> Type) -> P unit -> P u;
Unit = (A : Type) -> A -> A;
unit : Unit = A => x => x;
Unit_0 : Type = (u : Unit_B ~ 0) @-> (P : Unit -> Type) -> P unit -> P u;
unit_0 : Unit_0 = u @=> P => x => x;
Unit_1 = (u : Unit_0 ~ 1) @-> (P : Unit_0 ~ 1 -> Type) -> P unit_0 -> P u;
unit_1 : Unit_1 = u @=> P => x => x;
Unit_2 = (u : Unit_1 ~ 1) @-> (P : Unit_1 ~ 1 -> Type) -> P unit_1 -> P u;
unit_2 : Unit_2 = u @=> = P => x => x;
Γ |- A : Type Γ, x : A |- B : Type
-----------------------------------
Γ |- (x : A) @-> B : Type
Γ |- A : Type Γ, x : A |- M : T[]
-----------------------------------
Γ |- (x : A) @=> M : (x : A) @-> T
Γ |- M : (x ~ n) @-> T $ 2 ~ 1
------------------------------------
Γ |- @M : [x := ] $ 1
False_0 = (f ~ 0) @-> (A : Type $ 0) -> A;
False_1 = (f ~ 1) @-> (P : False_0 -> Type) -> P f;
False_2 = (f ~ 1) @-> (P : False_1 -> Type) -> P f;
False_3 = (f ~ 1) @-> (P : False_2 -> Type) -> P f;
@fix(1, (G ~ _) => (False ~ G) =>
(f $ G) @-(1)> (P : False@G $ 0 ~ G -> Type) -> P f);
False : Unit $ 0 ~ 0
(f $ 0 ~ 0) @-(1)>
(P : False@0 $ 0 ~ 0 -> Type) -> P f
False @-> (f : f @-> @False f) -> Type;
(False $ 0 ~ 0) @-> (f : (f ~ 0) @-> @False f) -> Type;
incr = (x : Int) => x + 1;
id
: (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
id = id ((A : Type) -> (x : A) -> A) id;
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
int_or_string
: (pred : Bool) -> (x : pred Type Int String) -> pred Type Int String
= (pred : Bool) => (x : pred Type Int String) => x;
x
: (x : Int) -> Int
= int_or_string true;
y
: (x : String) -> String
= int_or_string false;
mergesort == bubblesort
(A : Type) -> (l : List A) -> mergesort l == bubblesort l;
uip : (A : Type) -> (x : A) -> (eq : x == x) -> eq == refl = _;
Type 0
Type 1
Type 2
(x : Int $ 2) => x + x;
(x0 : Int) => (x1 : Int) => x0 + x1;
(x : Nat 2) => x + x;
(x0 : Nat) => (x1 : I_nat) => _;
(x : A $ 4) => (x : Nat $ 4 = 1; x)
incr = (x : Int) => x + 1;
User =
| Anonymous({ name : string })
| Registered({ id : int; name : string });
is_registered = user =>
user
| Anonymous(_) => false
| Registered(_) => true;
name_of_registered_user = (user : User & is_registered(user)) =>
user
| Registered { id; name } => Registered { id; name }
(x
x => M
M N)
true = x => y => x;
false = x => y => y;
Type : Type;
Fix = Fix $ 0 -(0)> ();
(x : Fix $ 0) =(0)> x x;
id = (A : Type) => (x : A) => (
@debug(x)
);
find_user : (id : Nat) -> Eff [DB.read] User;
x = @debug.db(find_user(1));
f = id(x => x);
User = {
parents : List User;
};
Exist<A> = {
x : A;
};
_A `unify` Int
id
: <A>(x : A) -> A
= (x : _A) => x;
Bool : Type = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
Bool : Type = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
id
: <A>(x : A) -> A
= x => x;
f = id(1)
nat_or_string
: (pred : Bool) -> (x : pred Type Nat String) -> pred Type Nat String
= (pred : Bool) => (x : pred Type Nat String) => x;
(x : Nat) ->? Nat
Socket : {
close : (sock : Socket$) -> ();
} = _;
[@wasm] [@parallel]
f = List.map;
f = (sock : Socket$) => Socket.close sock;
double = (x : Nat $ 2) => x + x;
f = x => double x + double x;
make = (l : Int & x >= 0) =>
f
: (x : Nat) -> Nat
= nat_or_string true;
g
: (x : String) -> String
= nat_or_string false;
main : IO ()
f x
arr => (
(x, arr) = Array.get(arr, 0);
(y, arr) = Array.get(arr, 1);
(x + y, arr)
);
pred (1) (0)
zero = z => s => z;
succ = n => z => s => s (n z s);
one = z => s => s z;
two = z => s => s (s z);
three = z => s => s (s (s z));
(x : ? -> Nat) => x x;
(x => x(x))(x => x(x))
((x : Int) => x + 1) 1
1 + 1
2;
(A : Type) => (x : A) => x;
x + 1 = 2
f (x + 1) = f (2)
(x => x - 1) (x + 1) = (x => x - 1) (2)
x + 1 - 1 = 2 - 1
x = 2
incr = (x : Int) => x + 1;
id
: (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
Id = (A : Type) => A;
f
: (x : String) -> String
= id String;
g
: (x : Nat) -> Nat
= id Nat;
incr = x => x + 1;
incr 1 === 1 + 1
(P : Nat -> Type)
P 0
P n -> P (1 + n)
P 5
(P 0)
P 0 -> P (1)
P 1 -> P (2)
P 2 -> P (3)
Type : Type
Type 0 : Type 1
Type 1 : Type 2
((A : Type 0) -> A -> A) : Type 0
((A : Type 1) -> A -> A) : Type 2
((A : Type 0) -> A -> A) : Type 1
((A : Type 1) -> A -> A) : Type 2
absurd : (A : Type) -> A = _;
if : (b : Bool) -> (A : Type) -> A -> A -> A;
Bool = (A : Type) -> A -> A -> A;
ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b = _;
Bool = (P : Bool -> Type) -> P true -> P false -> P b;
Bool = (b : Bool) @-> (P : Bool -> Type) -> P true -> P false -> P b;
ind : (L : Level) ->
(b : Bool (1 + L)) -> (P : Bool L -> Type) -> P true -> P false -> P (lower b) = _;
(n : Nat) -> S n != n
(n : Nat (1 + L)) -> S (lower n) != (lower n)
3 + 4 = 7
S S S Z + S S S S Z = S S S S S S S Z
2 * 3
S S Z * S S S Z = S S S S S S Z
Bool = (A : Type) -> A -> A -> A;
true : Bool = A => x => y => x;
false : Bool = A => x => y => y;
Bool = (A : Type) ->
((G : Grade) -> A $ G) $ 1 ->
((G : Grade) -> A $ G) $ 1 ->
((G : Grade) -> A $ G) $ 1;
true : Bool = A => x => y => (
_ = y 0;
x
);
false : Bool = A => x => y => (
_ = x 0;
y
);
Nat = (A : Type) -> A -> (A -> A) -> A;
Nat = (A : Type) ->
A $ 1 ->
((G : Grade) -> (A -> A) $ G) $ 1 ->
A $ 1;
zero : Nat = A => z => s => (
_ = s 0;
z
);
one : Nat = A => z => s => (
s = s 1;
s z
);
two : Nat = A => z => s => (
s = s 2;
s (s z)
);
three : Nat = A => z => s => (
s = s 3;
s (s (s z))
);
(x : Nat $ 1) => (y : Nat $ mul_copies(x)) => x * y
1 : Nat
1 : Int
f = (x : Int) => x;
f 1;
add : (A <: Number) -> A -> A -> A = _;
add Nat 1 1 : Nat
add Int -1 1 : Int
add Ratio (-1 / 1) (1 / 2) : Ratio
(-A) -> +B
Array A
Array Nat :> Array Int
Array Int :> Array Nat
f : (Nat -> Nat) -> Nat = _;
f ((x : Int) => 1)
f ((x : Int) => 1)
=
Decidability
Consistency
Impredicativity
Abstractions
Induction
Subtyping
Substructural
Unit_B = (A : Type) -> A -> A;
unit_b : Unit_B = A => x => x;
Unit_0 = (u : Unit_B) @-> (P : Unit_0 -> Type) -> P unit_b -> P u;
unit_0 = _;
@self()
Unit_0 = (u) @-> (P : Unit -> Type) -> P u
Closed A = (G : Grade) -> (A $ G)
(Unit $ 0 ~ 1) @=> u @-> (P : @Unit -> Type) -> P u;
(False $ 0 ~) @-> (f : f @-> @False f $ 0 ~ 1) -> Type;
(False $ 0 ~ 2) @->
(I : I -> (f : ))
(A : Type $ 0 ~ 1) => (x : A $ 1 ~ 0) => x;
(A : Type) => x => (x : A $ 1 ~ 0);
(tag : Bool $ 1 ~ 1, payload : tag | true => Int | false => String)
incr = x => x + 1;
two = incr(1);
two = (x => x + 1)(1);
two = (x + 1)[x := 1];
two = 1 + 1;
two = 2;
omega = (x => x(x))(x => x(x))
(x(x))[x := (x => x(x))]
(x => x(x))(x => x(x))
(x(x))[x := (x => x(x))]
(x => x(x))(x => x(x))
(let x = 1 in x + 1)
(x + 1)[x := 1]
1 + 1
2
(let x = 1 in x + 1)
(x => x + 1)(1)
(x + 1)[x := 1]
(let x = e0 in e1)
(x => e1)(e0)
e1[x := e0]
(let (x, y) = (1, 2) in x + 1)
((x, y) => x + 1)(1, 2)
x + 1[x := 1][y := 2]
x + 1[x := 1]
1 + 1
f = () => console.log(3);
f(console.log(1), console.log(2));
(() => console.log(3))(console.log(1), console.log(2));
console.log(3)
let f = fun () -> fun () -> print_endline "3" in
f (print_endline "1") (print_endline "2")
1 + (2 + (3 + (4 + (5 + 6))))
(1 + 2) + (3 + 4) + (5 + 6)
(1 + 2) + ((3 + 4) + (5 + 6))
(x => x(x))(x => x(x))
two = (
x = 1;
x + 1
);
incr = (x $ 1) => x + 1;
double = x => x + x;
int_or_string = (b : Bool) =>
(x : b | true => Nat | false => String) => x
id : <A>(x : A) -> A = x => x;
id : (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
Id = (A : Type) => A;
(x, y) = (x = 1, y = 2);
Joao = { id = 1; name = "João"; };
x = Joao.id;
l : Option Nat = Some 1;
User = { id : Nat; name : String; };
Either A B =
(tag : Bool, tag | true => A | false => B);
data%Status =
| Authorired
| Banned { reason : String; };
// TODO: linearity constraints
----------------
Γ |- Type : Type
Γ |- A : Type Γ, x : A |- B : Type
-----------------------------------
Γ |- (x : A) -> B : Type
Γ |- A : Type Γ, x : A |- M : B
--------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- M : (x : A) -> B Γ |- N : A
---------------------------------
Γ |- M N : B[x := N]
Γ |- t : A Γ, A : Type, x : A |- B : Type
------------------------------------------
Γ |- @ind(t, A. x. B) : B[A := A][x := t]
---------------------
Γ | Δ |- M $ n : Type
--------------------
Γ | • |- Type : Type
Γ |- A : Type Γ, x : A |- B : Type
-----------------------------------
Γ | • |- (x : A) -> B : Type
Γ |- A : Type Γ, x : A |- M : B
--------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- M : (x : A) -> B Γ |- N : A
---------------------------------
Γ |- M N : B[x := N]
((x : Socket) => Socket.close x)
Fix = (x : Fix $ 2) -> () -(0)> ();
fix = (x : Fix $ 1) =(0)> x;
Type : Type $ (n : Nat)
Nat : Type $ (n : Nat)
zero : Nat
succ : Nat -> Nat
(Type, Nat) @-> (Type : Type $ n, Nat : Type $ n);
Type @-> Type
Nat = n @-> (P : Nat -> Type) ->
P zero -> ((n : Nat) -> P n -> P (succ n)) -> P n;
zero = P => z => s =>
Grade =
(A : Type) -> A -> ((G : Grade) -> (A -> A) $ G) -> A
Γ |- A : Type Γ |- n : Grade
-----------------------------
Γ |- M : A $ n
f = (x : Nat $ 2) => x + x;
@Type : Type
Type = @Type;
Bool = (A : Type) -> A -> A -> A;
Closed (El : Type) => = Closed @=>
(T : Type) => (more : Bool) -> more T (());
Closed Unit false
Nat = Nat @=> (A : Type) -> A -> (Nat -> A) -> A;
fold = fold @=> (n : Nat) => A => z => s =>
n A z (pred => fold A )
// Weird
Never = (A : Type) -> A;
Stop = (A : Type) -> (b : Never) -> b A;
Apply = (x : Never) -> (P : (x : Never) -> x Type) -> P x;
(s : Stop) => s
stop : Stop = A => b => b A;
Id = (A : Type) -> (B : Type) -> B -> A;
Apply = (x : Never) -> (P : (x : Never) -> x Type) -> P x;
apply : Apply = (x : Never) => (P : (x : Never) -> x Type) =>
(x : Never) => x;
Bool =
b @-> (A : Type $ 0) -> A $ 1 -> A $ 1 -> A;
(x : (x : A) => A) => x
prefix _ infix
prefix _ infix _ infix _ suffix
x => {
x
}
x => { x }
(1, )
(1, ...R)
(1, 2,)
{ a; b }
x | 0
6 + (6 / 6)
1 + (2 * 3) + 4
Bool = (A : Type) -> |A| -> |A| -> |A|;
Bool = (A : Type) -> [A] -> [A] -> [A];
(f : A $ 2) =>
Γ | Δ, x |- (x : A $ n) -> B : Type
------------------------------------
Γ | Δ |- (x : A $ 1 + n) -> B : Type
Γ | Δ |- A : Type Γ, x : A | Δ |- B : Type
----------------------------------------
Γ | Δ |- (x : A $ 0) -> B : Type
Γ |- A : Type Γ |- G : Grade
-----------------------------
Γ |- M : A $ G
Γ | Δ |- A : Type Γ, x : A | Δ, x * 0 |- B : Type
--------------------------------------------------
Γ | Δ |- (x : A) -> B : Type
0 * Γ |- A : Type 0 * Γ |- G : Grade
-------------------------------------
0 * Γ |- A $ G : Type
Γ |- o Γ |- M : A
0 * Γ |- G : Grade
------------------------------
G * Γ |- |M| : A $ G
Γ |- M : A $ G Γ, x : A * G |- N : B
--------------------------------------
Γ, x : A * G |- |x| = M; N : B[x := N]
Γ |- A : Type
---------------
Γ |- |A| : Type
Γ |- o Γ |- M : A
0 * Γ |- G : Grade
------------------------------
G * Γ |- M : |A|
Γ |- M : A $ G Γ, x : A |- N : B
--------------------------------------
Γ, x : A * G |- |x| = M; N : B[x := N]
Closed (|A| : Type $ 0) = (|G| : Grade $ 0) -> A $ G;
(G : Grade $ 1) => (|x| : )
|x : Nat| = M; N
|x : Nat| = _; _
Closed A = (G : Grade $ 1) => (A * G);
(x : Closed Nat $ 1) => (G : Grade $ 2) =>
(((x : Nat $ G) => (succ x $ G)) (x G));
f : (G : Grade $ 2) -(G)> Nat = _;
g : (G : Grade $ 1) -(G)> Nat = f; // subtyping
// great
(M)
<M>
[M]
{M}
|M|
// inverse
)M(
>M<
]M[
}M{
// consider
/M\
\M/
A core language, maybe try full linear + closed and add RC as a feature? Sum types can take closed terms.
Bool = (A : |Type|) -> (then : |A|) -> (else : |A|) -> |A|;
Γ | • |- M <= A
-----------------
Γ | • |- M <= |A|
Γ, x : A | Δ¹ |- M : |A| Γ, x : A | Δ¹ |- N : B
------------------------------------------
Γ | Δ¹, Δ² |- |x : A| => M : (|x| -> B[x := ]
Closed A = (G : Grade $ 1) => (A $ G)
Fix = ()
Nat =
Bool = (A : Type $ 0) -> (then : |A|) -> (else : |A|) -> |A|;
Nat = (A : Type $ 0) -> (zero : A) -> (succ : |(acc : A) -> A|) -> A;
zero : Nat = A => zero => succ => (|| = succ; zero);
succ (pred : Nat) : Nat = A => zero => succ =>
(pred A zero succ;
Dyn A = (G : Grade $ 1) -(G)> A;
Nat = (A : Type $ 0) -> (zero : A) -> (succ : Dyn ((acc : A) -> A)) -> A;
zero : Nat = A => zero => succ => (
_ = succ 0;
zero
);
succ (pred : Nat) : Nat = A => zero => succ => (
succ = (G : Grade $ 1) => succ (1 + G);
);
@Nat = n @-> (P : Nat -> Type) ->
P (n @=> P => z => s => (_ = s 0; z)) ->
((pred : Nat) ->)
λx. x
∀P. P true → P false → ∀b. P b
Dyn A = (G : Grade $ 1) -(G)> A;
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
Nat = (A : Type $ 0) -> A -> Dyn (A -> A) -> A;
zero = A => z => s => ()
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
Nat = n @-> (P : Nat -> Type) -> P zero ->
Dyn ((pred : Nat) -> P pred -> P (succ pred)) -> P n;
zero = P => z => s => z;
Nat = (A : Type $ 0) -> A -> |A -> A| -> A;
zero = A => z => s => (|| = s; z);
one = A => z => s => (|s1| = s; s1 z);
two = A => z => s => (|s2, s1| = s; s2 (s1 z));
Nat = (A : Type $ 0) -> A -> |A -> A| -> A;
zero : Nat = A => z => s => (s = s 0; z);
succ (pred : Nat) : Nat = A => z => s => (
x = pred
);
Fix = (self : |Fix|) -> ();
|fix : Fix| = self => (
|f, ...rest| = self;
f(rest);
);
split : ((G : Grade) -> A $ (1 + G)) -> (A, (G : Grade) -> A $ G) = ?
@Fix = (self : (G : Grade) -(G)> Fix) -> ();
fix : (G : Grade) -(G)> Fix = G => self => (
self : (G : Grade) -> Fix $ (1 + G)
= G => self (1 + G);
(f, self) = split self;
f(self);
);
fix 1 fix
SNat = |(A : Type $ 0) -> A -> |A -> A| -> A|;
@Nat : Nat -> Type;
@zero : Nat zero;
@succ : (@pred : Nat pred) -> Nat (succ pred);
Nat k = (A : Type) -> A -> (A -> A) $ k -> A;
zero = A => z => s => z;
succ pred = A => z => s => s (pred A z s);
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
Nat = n @-> (P : Nat $ 0 -> Type $ 0) ->
P zero -> ((pred : Nat $ 0) -> P pred -> P (succ pred)) $ n -> P n;
zero = P => z => s => z;
succ pred = P => z => s => s (pred P z s);
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
Nat = n @-> (P : Nat $ 0 -> Type $ 0) ->
P zero -> ((pred : Nat $ 0) -> P pred -> P (succ pred)) $ n -> P n;
zero = P => z => s => z;
succ pred = P => z => s => s (pred P z s);
Nat = n @-> (A : Type) -> A -> (A -> A) $ n -> A;
zero : Nat = n @=> P => z => s => z;
succ (pred : Nat) : Nat = n @=> P => z => s => s (pred P z s);
f = () => () => 1;
x = (G : Grade) => (x : Nat $ G) => _;
A $ G
|M : A| $ G
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
SRc : (A : Type $ 0) -> (n : Nat $ 1) -> Type;
next : (A : Type $ 0) -> (pred : Nat $ 0) -> SRc (succ pred) A -> (A, SRc pred A);
free : (A : Type $ 0) -> SRc zero A -> ();
Nat = n @-> (A : Type) -> A -> SRc n (A -> A) -> A;
zero = n @=> A => z => s => (() = free (A -> A) s; z);
succ = pred => n @=> A => z => s => (
(s1, s) = next (A -> A) pred s;
s1 (pred A z s)
);
SRc A n = () -> n Type () (acc => (A, acc));
next A pred rc = rc ();
free A rc = rc ();
(x : Unit) =>
(x : EUR $ 2) -(3)> USD
Nat : Type;
zero : Nat;
succ : Nat -> Nat;
SRc : (n : Nat) -> (A : SRc n Type) -> Type;
id = (A : SRc 0 Type) => A (A => (
(x : A) => x,
A
));
same : (n : Nat $ 0) -> (A : Type $ 0) ->
(rc : SRc A (succ n)) ->
fst (next rc) == fst (snd (next rc));
Nat = n @-> (A : Type $ 0) -> A -> (A -> A) $ n -> A;
zero = n @=> A => z => s => (
() = A;
() = s;
z
);
succ = pred => n @=> A => z => s => (
() = A;
(s1, s) = s;
s1 (pred A z s)
);
( $ ) n A = n Type () (acc => (A, acc));
next A pred rc = rc;
free A rc = (() = A; rc);
@E : (A : E Type) -> Type;
@E A = A;
(A : E Type) => (x : E ())
id = (A : Type) => (x : A) => x;
id = (A : Type $ 0) =>
Nat : Type;
zero : Nat;
succ : (pred : Nat) -> Nat;
Dyn : (A : Type) -> Type;
Dyn A = (n : Nat) -> A $ n;
Nat = n @-> (A : Type $ 0) -> A ->
true = x => y => x y;
false = y => x => y x;
weak = (n : Nat $ 1) => n () () (() => ());
|x|
t = A => (x : A) => x;
Fix = (x : Fix $ 0) -(0)> ()
fix = x => x x;
Double = (m : Nat $ 1) => (n : Nat, eq : m == n);
Bool = b @-> (A : Type $ 0) -> b Type |0 1 -> A;
Fix = (x : Fix $ 0) -(0)> ();
fix : Fix = x => x x;
Fix = (x : Fix $ 0) -> (() $ 0 -> ()) -> ();
fix : Fix = (x : Fix $ 0) => k => k (x x (() => ()));
False = (A : Type $ 0) -> A;
Fix = (x : Fix $ 0) -> (K : Type $ 0) -> ((False $ 0) -> K) -> K;
fix : Fix = (x : Fix $ 0) => k => k (x x False (f => f));
Fix = ∀(x : Fix). Π(k : ∀(u : Unit). Unit). Unit;
fix : Fix = Λ(x : Fix). λk. k (x x (λu => u));
Fix = (x : Fix $ 0) -> ();
fix : Fix = x => x x;
main : (n : Nat $ 0) -> (() -> ()) $ n;
main2 = (n : Nat $ 0) -> (
() = x;
1
);
x @=> b => b _ (instance, x) None;
Nat = n @-> (P : Nat $ 0 -> Type $ 0) -> P zero ->
((pred : Nat $ 0) -> P pred -> P (succ pred)) $ n -> P n;
succ pred = n @=> P => z => s => s (pred P z s);
List(A : Type) : Type;
fold<A, K>(l : List(A), initial : K, f : A -> K -> K) : K;
length<A>(l : List(A)) : (List(A), Nat);
length(l) = fold(l, 0, x => (l, n) => (x :: l, 1 + n));
List(A) = (K : Type) -> K -> |A -> K -> K| -> K;
`A
~a
(x : Nat & x > 1) => _;
(x : Nat & x > 1) => _;
(x : Nat | x > 1) => _;
(x : Nat ~ x > 1) => _;
(x : ~Nat) => x;
(x : &Nat) => _;
(x : ^Nat) => x;
(x : 'Nat) => x;
List<A> = (K : Type) -> K -> |A -> K -> K| -> K;
length<A>(l : List<A>) -> (l : List<A>, s : Nat);
length<A>(l : &List<A>) -> Nat;
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool -> Type $ 0) -> |P true| -> |P false| -> |P b|;
true = P => then => |else| => then;
false = P => |then| => else => else;
case : &Bool -> (K : Type $ 0) -> |K| -> |K| -> |K|;
Fix = &Fix -> ();
fix : Fix = x => x;
x = (&b)
List<A : Type> : Type;
length<A>(l : List<A>) : (l : List<A>, s : Nat);
length<A>(l : &List<A>) : Nat;
length(l : List<A> $ 1) : Nat;
Bool = <A>(then : A, else : A) -> A;
true : Bool = _;
false : Bool = _;
clone(b : Bool) : (l : Bool, r : Bool) = b((true, true), (false, false));
weak(b : Bool) : Unit = b((), ());
Box<A> = <K>(with : A -> K) -> K;
Box<A> = <K>(with : A -> K) -> K;
&Box<A> = <K>(with : &A -> K) -> K;
borrow<A : Borrow, K>(box : Box<A>, k : &Box<A> -> K) : (box : Box<A>, k : K) =
box(x => (
k = k(with => with(x));
(with => with(x), k);
));
Box = <K>(with : Socket -> K) -> K;
&Box = <K>(with : &Socket -> K) -> K;
borrow = <K>(box : Box, k : &Box -> K) : (box : Box, k : K) =>
box(socket => (
k = k(with => with(socket));
(with => with(socket), k);
));
f = (box : &Box) => box((socket : &Socket) => _);
id
: (A : Type $ 0) -> (x : A $ 1) -> A;
= (A : Type $ 0) => (x : A $ 1) => x;
Socket : {
send : (sock : Socket, message : String) -> (sock : Socket);
close : (sock : Socket) -> ()
} = _;
Socket : {
send : (sock : &Socket, message : String) -> ();
close : (sock : Socket) -> ()
} = _;
List : {
length<A>(l : &List<A>) : Nat;
} = _;
f = sock => (
Socket.send(sock, "a");
Socket.send(sock, "b");
Socket.close(sock);
);
f = sock => (
sock = Socket.send(sock, "a");
Socket.send(sock, "b")
);
double = (x : Nat $ 1) => x + x;
Box<A> = <K>(with : A -> K) -> K;
&Box<A> = <K>(with : &A -> K) -> K;
borrow<A : Borrow, K>(box : Box<A>, k : &Box<A> -> K) : (box : Box<A>, k : K) =
box(x => (
k = k(with => with(x));
(with => with(x), k);
));
make : (x : Int & x >= 0) => _;
Lifetime : Type;
zone<K>(k : <L>() -[L]> K) -> K;
borrow<L>(x : A) : &<L>A ! L;
Nat = n @-> (A : Type $ 0) -> A ->
(x : &Nat $ 1) => _;
&<L : Lifetime $ 0>(A : Type) : Type;
List<A : Type> : Type;
length<A>(l : List<A>) : (l : List<A>, s : Nat);
length<L, A>(l : &<L>(List<A>)) : Nat ! F<L>;
read(file : String) : String ! [IO];
read : (file : String) -[IO]> String;
<L>(x : &<L>Nat) : (L : Lifetime, (A : Type, x : A)) =>
(L, (A = &<L>Nat, x));
add : <L_n : Lifetime $ 1, L_m : Lifetime $ 1>(n : Borrow<L_n>)
Box<A> = <K>(with : A -> K) -> K;
box<A>(x : A) : Box A = with => with(x);
Borrow<L, Box<A>> = <K>(with : Borrow<L, A> -> K) -> K;
borrow<A : Borrow, K>(box : Box<A>, k : <L>(box : &<L>Box<A>) -> K)
: (box : Box<A>, k : K) =
box(x => (
k = k(with => with(x));
(with => with(x), k);
));
(x : &<A>Int) =>
(fst : A, snd : fst == fst)
(fst : Type, snd : fst)
Bool : Type;
Null : Type;
(Int64 : Type) & {
} = _;
(Memory : Type) & {
length(mem : Memory) : Int64;
get(mem : Memory, addr : Int64 & addr < length(mem)) : Int64;
} = _;
C_bool = (A : Type) -> A -> A -> A;
I_bool(Bool : Type, true : Bool, false : Bool, b : Bool) =
(P : Bool -> Type) -> P true -> P false -> P b;
I_unit(Unit : Type, unit : Unit, u : Unit) =
(P : Unit -> Type) -> P unit -> P u;
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = P => x => x;
Bool =
(Array(A : Type) : Type) & {
} = _;
Array(mem : Memory)
Pair mem = Int64
Nat = (z : Bool, s _ )
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = P => x => x;
Unit : Type;
unit : Unit;
Unit = (u : Unit, i : (P : Unit -> Type) -> P unit -> P u);
unit = (unit, P => x => x);
ind : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u
= u => snd u : (P : Unit -> Type) -> P unit -> P (fst u);
(Int64 : Type) & {
} = _;
(Memory : Type) & {
length(mem : &Memory) : Nat64;
get(mem : &Memory, addr : Nat64 & addr < length(mem)) : Nat64;
} = _;
Ptr_type : {
@Ptr_type(mem : &Memory, addr : Int64) -> Type
size(mem : &Memory, addr : Int64) : Int64;
};
Word_size = 8;
Block(mem : &Memory, size : Nat64) =
(addr : Int64 & addr + size < length(mem));
Usize(mem : &Memory) : Type = Block(mem, Word_size);
Ptr_type : {
(mem : &Memory, addr : Int64) -> Type
size(mem : &Memory, addr : Int64) : Int64;
};
Usize(mem : &Memory, addr : Int64) : Type = addr + Word_size < length(mem);
Pair(L : Ptr_type, R : Ptr_type)(mem : Memory, addr : Int64) : Type =
(l : L(mem, addr))
Usize = {
*<mem>(size : )
};
String(mem : &Memory) =
(len : Usize(mem)) & Block(mem, *len);
Pair(mem : Memory, L : Type, R : Type) =
(addr : Int64, addr < length(mem), )
Bool : (A : Type) -> A -> A -> A;
x @=> x; // negative?
x @=> y => x; // negative?
(@x : T) @=> b => b T (Some (1, x)) None;
(@x : T) @=> b => b T (Some (1, x)) None;
Nat = (A : Type) -> A -> (Nat -> A) -> A;
Nat = n @-> (P : Nat -> Type) -> P zero -> ((pred : Nat) -> P (succ pred)) -> P n;
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool ∞ $ 0 -> Type) -> P (true ∞) -> P (false ∞) -> P (b ∞);
Nat = n @-> (P : Nat ∞ $ 0 -> Type) ->
P zero -> ((pred : Nat) -> P (succ pred)) -> P n;
Nat = n @-> (A : Type) -> A -> ((pred : Nat) -> n = succ pred -> A) -> A;
sized(n : Nat)(fold) @=>
A => z => s => n A z (pred => lower => s (fold pred lower A z s));
fold = (fold : (n : Nat) -> (A : Type) -> A -> (A -> A) -> A) @=>
n => A => z => s => n A z (pred => s (fold pred A z s));
fold = (fold : (n : Nat) -> (A : Type) -> A -> (A -> A) -> A) @=>
n => A => z => s => n A z (pred => s (fold A z ));
Pair(A : Type, B : Type) =
(K : Type $ 0) -> |A -> B -> K| -> K;
id : (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
y = id(String);
x = id(Nat)(1);
f = x => x;
x => y => y x;
x => y => x y;
x => y => x;
x => y => y;
x => x + x;
Socket : {
connect : () -> Socket;
send : (sock : &Socket, msg : String) -> ();
close : (sock : Socket) -> ();
} = _;
(sock : Socket) => (
Socket.send(sock, "hi");
Socket.close(sock);
1
);
Memory : {
malloc : (size : Nat) -> Memory;
free : (mem : Memory) -> ();
} = _;
Omega = (x => x x) (x => x x);
(x => x x) (x => x x)
(x => x x) (x => x x)
Nat = n @-> (P : Nat -> Type) ->
|P zero| -> |(pred : Nat) -> P (succ pred)| -> P n;
sized(n : Nat)(fold) @=>
A => z => s => n A z (pred => lower => s (fold pred lower A z s));
sized(size : (x : T) -> Nat))(fold : (y : T) -> size x = succ (size y) -> K) @=> _;
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
Nat = (P : Nat -> Type)
False = (A : Type) -> A;
Fix = (x : Fix) -> False;
fix : Fix = (x : Fix) => x x;
omega = fix(fix);
(x => x x)(x => x x);
Term =
| x
| x => M
| M N;
(x => M) N === M[x := N];
(x => x x) (x => x x)
(x x)[x := (x => x x)]
(x => x x) (x => x x)
((x => x) 1)
(Int -> Fix Int)
(x => x + x) 1 === (x + x)
(x => x x) (x => x x);
Bool : Type;
true : Bool;
false : Bool;
Bool = b @-> (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Nat : Type;
zero : Nat;
succ(pred : Nat) : Nat;
Nat = n @-> (P : Nat -> Type) -> P zero ->
((pred : Nat) -> n = succ pred -> P (succ pred)) -> A;
Unit (i : Size) : Type;
unit (i : Size) : Unit;
Unit i = u @-> (P : (u : Unit i) -> Type) -> P (unit i) ->
Unit (i : Size) : Type;
unit (i : Size) : Unit i;
Unit α = u @-> (P : ((β : Size < α) -> Unit β) -> Type) ->
P (β => unit β) -> P (β => u β);
unit α = P => x => x;
Unit : Type;
unit : Unit;
Unit = (α : Size) -> Unit α;
unit = (α : Size) => unit α;
ind : (u : Unit) -> (P : Unit -> Type) -> P unit -> P u;
= u => P => x => u 0 (β => P )
fold (u : Unit) = A => x =>
(u : Unit)
Size = (A : Type) -> (A -> A) -> A;
next (s : Size) = A => n => n (s A n);
le : (α : Size) -> (β : Size) -> Type;
Nat : (β : Size) -> le β α -> Type
(Nat [α]) @=>
(A : Type) -> A -> ((β : Size) -> (lower : le β α) -> Nat β lower -> A) -> A;
Size = (A : Type) -> (Size -> A) -> A;
Size (i : Size i) : Type;
Size α = s @-> (A : Type) -> ()
fold : (n : Nat) -> (A : Type) -> A -> (A -> A) -> A;
sized(fold, n) @=> A => z => s =>
n A z (pred => lower => fold pred lower A z s);
x @=> x
Nat @=> (A : Type) -> A -> (Nat -> A) -> A;
Nat @=> n @-> (P : Nat -> Type) -> P zero ->
((pred : Nat $ 0) -> P pred -> P (succ pred)) $ n -> P n;
Nat @=> (A : Type) -> A -> (A -> A) -> A;
[@teika.core.ir]
Fix = Fix -> ();
fix : Fix = (fix) -> clone(fix)(fix)
borrow : &<L>T $ n;
Size = (A : Type) -> (A -> A) -> A;
next (i : Size) = A => s => s (i A s);
Nat (i : Size) : Type;
Nat α = n @-> (A : Type) -> A ->
((β : Size) -> (pred : Nat) -> A) -> A;
fold [s] (n : Nat) = A => z => s =>
n A z (pred => lower => s (fold pred lower A z s));
Unit (α : Size) : Type;
unit (α : Size) : Unit α;
Unit α = u @-> (P : ((β : Size) -> β < α -> Unit β) -> Type) ->
(P (β => lower => unit β)) -> (P (β => lower => u β));
unit α = P => x => x;
Unit = (α : Size) -> Unit α;
unit = (α : Size) => unit α;
Nat (i : Size) : Type;
Nat α = n @-> (P : ((β : Size < α) -> Unit β) -> Type) ->
P (β => unit β) -> P (β => u β);
unit α = P => x => x;
Nat α = n @-> (A : Type) -> A -> ((β : Size) -> α < β -> Nat β -> A) -> A;
fold α = n => A => z => s
n A z (fold (β => lower => pred => fold β lower pred A z s));
(@Unit : Type) @=> (u : Unit) @-> (P : Unit -> Type) ->
P ((u : Unit) @=> P => x => x) -> P u;
@((Unit : Unit @-> Type) @=> I => u @->
(P : @Unit I -> Type) -> P (I unit) -> P (I u)) (refl);
(Unit : Unit @-> Type) @=> I => u @->
(P : @Unit I -> Type) -> P (@I unit) -> P (@I u)
(@T_False : Type) @=>
(@False : T_False) @->
(f : @((@T_f : Type) @=> ((f : T_f) @-> False f))) -> Type;
(@Unit : Unit) @-> Type;
(False) : Type -> Type;
(Unit ) @=>
I => u @-> (P : @Unit I -> Type) ->
P (u @=> P => x => x) -> P u;
()
unit : @Unit;
@unit
expected @Unit
received : (P : @Unit -> Type) -> P u -> P u;
expected : @Unit
received : @Unit
expected : @Unit
@Unit = (@Unit : Type) @=> @(u : Unit) @->
(P : Unit -> Type) -> P (@(u : Unit) @=> P => x => x) -> P (@fold u);
(@T : ) @-> (I : I @-> @T I -> Unit) -> Type;
(I : (I : T_I) @-> @T I -> Unit) -> Type
x : (P : Unit -> Type) -> P unit -> P x;
fold x : @u @-> (P : Unit -> Type) -> P unit -> P (@fold u);
(@T_False : Type) @=>
(@(False : T_False) @-> )
unit = _;
@x : (P : Unit -> Type) -> P unit -> P (@unit)
@u
Γ, x : A |- B : Type
-----------------------------
Γ |- @assume(x : A). B : Type
Γ, x : A |- B : Type Γ, x : A |- M : B
---------------------------------------
Γ |- @fix(x : A). M : @assume(x : A). B
Γ, x : A |- B : Type
----------------------------
Γ |- @self(x : A). B : Type
Γ |- M : @assume(x : A). B Γ |- A ≂ B
--------------------------------------
Γ |- @verify M : @self(x : A). B
Γ |- M : @self(x : T). T
--------------------------
Γ |- @unroll M : B[x := M]
Unit : @assume(@Unit : Type). Type
= @fix(@Unit : Type). @self(u : Unit). (P : Unit -> Type) -> P u -> P u;
Unit : @self(@Unit : Type). Type = @verify Unit;
Unit : Type = @unroll Unit;
unit : @assume(u : Unit). (P : Unit -> Type) -> P u -> P u
= @fix(u : Unit). P => x => x;
unit : @self(u : Unit). (P : Unit -> Type) -> P u -> P u = @verify unit;
unit : Unit = unit;
T = Unit @-> (I : I @-> @Unit I -> !Unit) -> Type;
@fix(@T_Unit : Type). @self(Unit : T_Unit).
(I : @fix(T_I : Type). @self(I : T_I). ) -> Type;
Unit : @assume(@Unit : Type)
unit : @assume(u : Unit). (P : Unit -> Type) -> P u -> P u
= @fix(u : Unit). (P : Unit -> Type) => (x : P u) => x;
unit = @verify()
Unit = @self(u : Unit). (P : Unit -> Type) -> P u -> P u;
@Unit = @verify Unit;
@fix(@u : Unit)
Nat = @fix(@Nat : Type). (A : Type) -> A -> (Nat -> A) -> A;
Nat = @verify Nat;
Unit = @fix(@Unit : Type). @self(u : Unit). (P : Unit -> Type) -> P u -> P u;
@Unit = @verify Unit;
unit = @fix(@u : Unit). (P : Unit -> Type) => (x : P u) => x;
@self(u : Unit). (P : Unit -> Type) -> P u -> P u
Nat_T = @assume(Nat : Type). Type;
@fix(Nat) : Type = (A : Type) -> A -> (@unroll Nat -> A) -> A;
@assume(@False) : Type. Type;
False = @fix(@False : Type). @self(f : False). (P : False -> Type). P f;
False = @verify(False);
@fix(@Unit) : Type. @self(u : Unit).
(P : Unit -> Type) -> P
Γ, x : A |- M : A
----------------------
Γ |- @fix(x) : A. M :
Γ, x : A |- B : Type
--------------------------------
Γ |- @fix(x : A). B : Self
@fix(False) : Type.
(P : @unroll False -> Type) ->
@fix(Unit) : Type.
(P : @unroll Unit -> Unit) -> P
unit : @self.open(u : Unit). (P : Unit -> Type) -> P unit -> P u;
False = @self(f : @self.close False). (P : @self.close False -> Type) -> P f);
False = @self.close False;
Bool : Type;
true : Bool;
false : Bool;
Bool = @self(b : Bool). (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Γ, x : A |- B : Type
----------------------------
Γ |- @self(x : A). B : Type
Γ, x : A |- B : Type Γ, x : A |- M : B
---------------------------------------
Γ |- @fix(x : A). M : @self(x : A). B
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- @unroll M : B[x := M]
Γ |- T : Type Γ, x : T |- M : T
-------------------------------- // TODO: avoid this
Γ |- @fix(@x : T). M : T
T_False = False @-> (f : f @-> @False f) -> Type;
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = @self(False : T_False). (f : T_f False) -> Type;
T_f = False => @self(f : T_f). @False f;
T_False = @fix(@T_False).
(T_f : @fix(@TT_f). @self(T_f : TT_f). (False : T_False T_f) -> Type)) => (
T_False = T_False T_f;
T_f = @T_f;
@self(False : T_False). (f : T_f False) -> Type;
);
T_f = @fix(@T_f). (
T_False = T_False T_f;
False => @self(f : T_f). @False f
);
T_False (T_f : Type) = @fix(@T_False).
@self(False : T_False). (f : T_f) -> Type;
T_f = @fix(@T_f). (False : T_False T_f) =>
@self(f : T_f). @False f;
@fix(@F_False : Type).
@self(False : F_False).
@self(T_f). @self(f : T_false T_f). @False f
T_False = @fix(@T_False). (T_f : Type) =>
@self(False : T_False T_f). (f : T_f) -> Type;
T_f = @fix(@T_f). (False : T_False T_f) => @self(f : T_f False). @False f;
@fix(@T_False2). T_False (T_f T_false2)
Unit = @fix(@Unit : )
Bool : Type;
true : Bool;
false : Bool;
Bool = @self(b : Bool). (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Unit = @fix(Unit). unit => @self(u : @Unit unit).
(P : @Unit unit -> Type) -> P @unit -> P u;
unit = @fix(unit). @fix(u : @Unit unit). P => x => x;
(P : Unit -> Type) -> P (@fix(u : Unit). P => x => x) -> P u
expected : @self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
received : @self(u : Unit). (P : Unit -> Type) -> P u -> P u;
(u : Unit) => @u
unit : Unit = @fix(u : Unit). P => x => x;
unit : _ = _;
Unit = @Unit unit;
unit = @unit;
unit = @fix(u). P => x => x;
T_False = False @-> (f : f @-> @False f) -> Type;
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = @self(False : T_False). (f : T_f False) -> Type;
T_f = False => @self(f : T_f). @False f;
T_False = @fix(T_False). T_f => (
T_False : Type = @T_False T_f;
T_False : (False : T_False) -> Type = @T_f;
@self(False : T_False). (f : T_f False) -> Type;
);
T_False = False @-> (f : f @-> @False f) -> Type;
T_False = @fix(@T_False : Type).
@self(False : T_False). (f : @self(f : ?) -> @False f) -> Type;
T_False = (T_f : Type) -> @fix(@T_false : Type).
@self(False : T_false). (f : T_f) -> Type;
T_f = (False : T_False) => @fix(@T_f : Type).
@self(f : T_f). @(False T_f) f;
False : T_False = T_f => @fix(False : @self(False : T_false). (f : T_f) -> Type).
(f : T_f) =>
()
Unit = @self(Unit : T_unit). (unit : @self(unit : Unit). @Unit unit) -> Type
Unit = @fix(Unit : Type).
T_False = False @-> (f : f @-> @False f) -> Type;
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = @self(False : T_False). (f : T_f False) -> Type;
T_f = False => @self(f : T_f False). @False f;
T_False = @fix(@T_False : Type). (
T_f = @fix(T_f). (
T_False = @self(False : T_False). (f : @T_f False) -> Type;
False => @self(f : T_f False). @False f
);
T_f = @
@self(False : T_False). (f : T_f False) -> Type;
);
Γ, x : A |- B : Type
---------------------------
Γ |- @self(x : A). B : Type
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- @verify M : A
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- @unroll M : B[x := M]
Γ
False
------------
Γ |- A $ n : Type
(f : Int $ 0) -> (x : Nat)
(x : Int $ 1) => x;
f : (x : Nat & x <= 5) -> _;
(x : Nat) => (x_le_5 : x <= 5) => _;
(A : *) -> (x : A) -> A;
(A : Type) -> (x : A) -> A;
Type @->
Type @=> forall =>
Type : Type @-> @Type = Type @=> @Type;
Id : @Type = (A : @Type) -> A;
@Type : Type;
@(->) : (A : Type) -> (B : (x : A) -> Type) -> Type;
@(=>) : (A : Type) -> (B : (x : A) -> Type) -> (M : (x : A) -> B x) -> Type;
Type = Type;
(->) A B =
(Type : Type @-> @Type) =>
(Type : Type @-> Type) =>
(A : Type $ 0) =
// TODO: is this valid?
(x : P (x => Type)) => _
-----------
String : Type;
Type : Type;
((x : String) -> String);
T : Type = (A : Type) -> (x : A) -> A;
f : (A : Type) -> (x : A) -> A = _;
(f String) : (x : String) -> String;
Type : Type
((A : Type) -> (x : A) -> A) : Prop
Type : Kind
Kind : Δ
Set of all sets that doesn't include themselves
Nat : Type 0
Type : Type
Type 0 : Type 1
Type 1 : Type 2
Type n : Type (1 + n)
Type : Type
Nat =
| Zero
| Succ (pred : Nat);
Nat0 = (A : Type) -> (zero : A) -> A;
Nat1 = (A : Type) -> (zero : A) -> (succ : (pred : Nat0) -> A) -> A;
Nat2 = (A : Type) -> (zero : A) -> (succ : (pred : Nat1) -> A) -> A;
@Nat : Type = (A : Type) -> (zero : A) -> (succ : (pred : Nat) -> A) -> A;
@fold (n : Nat) (A : Type) (acc : A) (f : A -> A) : A =
n A acc (pred => f (fold pred A z f));
(x => x x) (x => x x)
Nat (α : Size) = (A : Type) -> (zero : A) ->
(succ : (β : Size) -> β < α -> (pred : Nat β) -> A) -> A;
@fold [α] (n : Nat α) (A : Type) (acc : A) (f : A -> A) : A =
n A acc (β => lower => pred => fold β lower pred A (f acc) f)
Γ, α : Size |- T : Type
Γ, α : Size, x : (β : Size $ 0) -> β < α -> T |- M : T
--------------------------------------------------
Γ |- @fix(x [α] : T). M
f : (x : A) ->? B
f : (x : A) -> B
Type 0 : Type 1
Type 1 : Type 2
Nat = n @-> (A : Type) -> A -> (A -> A) $ n -> A;
List A = l @-> (K : Type) -> K -> (A -> K -> K) $ length l -> K;
O(length l)
Nat (α : Size) = (A : Type) -> (zero : A) ->
(succ : (β : Size) -> α = 1 + β -> (pred : Nat β) -> A) -> A;
Nat = (A : Type) -> A -> (Nat -> A) -> A;
Nat (mem : Memory) = (addr : Pointer & addr | 0 => _ | _ => )
Performance = _;
Proof = _;
Utils = _;
pred : (s : Size) -> Nat s -> Nat s;
pred : Nat -> Nat;
Nat : Type 1 = (l : Level $ 0) -> (A : Type l) -> A -> (A -> A) -> A;
// fold : (β : Size) -> β < α -> (n : Nat β) -> (A : Type) -> (acc : A) -> (f : A -> A) -> A
f : (x : -A) -> +B = _;
-(int list) +(string list) +int
Nat =
Id0 : Type 1 = (A : Type 0) -> A -> A;
id0 : Id0 = A => x => x;
Id1 : Type 2 = (A : Type 1) -> A -> A;
id1 : Id1 = A => x => x;
id1 Id0 id0
(x : P (x => Type)) => _
Nat = n @->
Γ, x : T $ n |- M : T
-----------------------------------
Γ |- @fix(x : T $ 1 + n). M : T
Nat : Type;
(0) : Nat;
(1 +) : (pred : Nat) -> Nat;
Nat = n @-> (P : Nat $ 0 -> Type $ 0) ->
P 0 -> ((pred : Nat) -> P (1 + pred)) -> P n;
(0) = P => z => s => z;
(1 +) pred = A => z => s => s pred;
Nat = n @-> (A : Type) -> A -> (A -> A) $ n -> A;
n => @fix(fold $ 1 + n).
A => acc => map => n A acc map;
(n : Nat) => (A : Type) => (acc : A) => =>
@fix(fold $ 1 + n). (n_ == n) =>
(A : Type) => (acc : A) => (map : A -> A) =>
n_ (_ => A) acc (pred => fold )
(n : Nat) =>
double (n : Nat) =
n Nat (0, 0) ()
is_even = (n : Nat) =>
n Bool true (@fix(not : Bool -> Bool $ 1 + n). b)
(x : A) => M
(x : P (x => Type)) => _;



2
x => y => (x y)[swap]
x => y => (y => x => x y) y x
(1)[x => x Int String]
(x : (A) $ b) => _
(x: A) (:) (A : Type)
T = A $ 5;
(A : Type : ) -> A -> A;
Type : Type;
Value : Type;
Prop : Type;
(A : Type) -> (x : A) -> A
Univ : Univ; // erasable
Prop : Univ; // irrelevant
Type : Univ; // relevant
// TODO: parametric
Γ $ 0 |- M : Univ
---------------------
Γ $ 0 |- @squash M : Type
(Γ, x : A) $ 0 |- B : Type
----------------------------
Γ $ 0 |- (x : A) -> B : Type
Γ $ 0 |- A : Univ Γ, x : A $ ∞ |- M : B
----------------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ $ 0 |- A : Type Γ, x : A $ 1 |- M : B
----------------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- M : (x : A) -> B Γ |- N : A
---------------------------------
Γ, Δ |- M N : B[x := N]
((x $ 0) : A) ->
((x : A) $ 0)
(x : (A $ 0))
(f : A -> B)
f : A $ 0
(f : A $ 0 : Univ) ->
Fix = Fix -> Type;
(x : Fix) => x x;
Type : (n : Nat) -> Type 0;
((x : A) -> B) : Type 2
(A : Type 1 : Type 0) => (x : A : Type 1) -> x;
(A : Type 2) => (x : A) => (x, x);
(A : Type $ 0) => (x : A $ 2) => (x, x);
(A : Type) => (x : A $ 2) => x
Kind =
| Erasable
| Irrelevant
| Multiplicative
Type : ()
Type : Type
Linear : Type
Type : Univ
Type : Type
(A : Linear)
((x : A) $ G)
(x : ) : Promise<T, E> => _
malloc : () -> (L : Lifetime);
free : (L : Lifetime) -> ();
lifetime : <A>(x : &A) -> Lifetime;
() -[Allocator Root]> ()
() -[Allocator One]> ()
add : (x : &Nat, y : &Nat) -> Nat;
add : (x : &Nat, y : &Nat) -[Borrow x | Borrow y]> Nat;
add : (x : &Nat, y : &Nat) -> Nat;
<L>(x : &<L>Nat) =[Zone L]> x + x;
(x : &Nat) =[Zone x]> x + x;
(x : &Nat) => (
(x1, x2) = x.copy()
(x1, x2)
)
Type : Univ;
Prop : Univ;
f = (A : Type : Univ) => (x : A : Type) => x;
(A : Prop : Univ) => (x : A : Prop) => _;
borrow : <K>(x : Nat, region : () -[Zone x]> K) -> K;
Type 0 : Type 1
Prop : Type 0
SFalse : Prop = (A : Prop) -> A;
False : Type = (A : Type) -> A;
f : SFalse -> False = _;
Unit : Prop = (A : Prop) -> A -> A;
(A : Type 0) => (u : Unit) => u (Type 0) A
Bool : Prop = (A : Prop) -> A -> A -> A;
(b : Bool) => b (Type 0)
(A : Type) => (x : (A : Prop) -> Prop) => x;
Fix : Type;
&Fix : Type;
Fix = &Fix -> A;
&Fix = &Fix -> A;
@Fix = f @-> (P : Fix -> Type) -> (x : Fix) -> P x -> P f;
Fix : Type;
fix : Fix;
Fix = (x : Fix) -> ();
fix = x => fix x;
&Fix : Type;
fix : Fix;
Fix = f @-> (P : Fix -> Type) -> P fix -> &Fix -> P f;
&Fix = f @-> (P : &Fix -> Type) -> P (&fix) -> &Fix -> P f;
fix = P => p_fix => x => x P p_fix x;
Type : Type;
Data : Type; // clonable?
Prop : Type;
Checking Compiling Hover on Type Typer tracking Partial rebuild Debugging Jump to definition Serialization
do {
const x = 1;
return x + 1;
}
(let x = 1; x + 1)
(x = 1; x + 1)
x => (
y = (
z = x;
x + 1
);
y + 2;
);
----------------
Γ |- Type : Type
Γ |- A : Type Γ, x : A |- B : Type
-----------------------------------
Γ |- (x : A) -> B : Type
Γ, x : A |- M : B
--------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- M : (x : A) -> B Γ |- N : A
---------------------------------
Γ |- M N : B[x := N]
clone : (x : Nat) -> (l : Nat, r : Nat) = _;
Array : {
get : <A>(arr : &Array A, i : Nat) -> (el : A);
set : <A>(arr : Array A, i : Nat, el : A) -> (arr : Array A);
size : <A>(arr : &Array A) -> (size : Nat);
} = _;
x[0] := x;
double = (x : &Nat) => x + x;
double = (x : &Nat $ 2) => x + x;
id = (A : Type $ 0) => (x : A) => x;
f = (x : Nat) => (x_le_5 : x <= 5) => x;
Unit =
| unit;
f = (n : Nat) => (x : Unit) => n;
(n : Nat) => (x : Unit) => (y : Unit) : Eq(f n x, f n y) => ()
f n unit == f n unit
Eq<A>(x : A, y : A) =
| refl : Eq(x, x);
refl
Erasable
Irrelevance
Duplicable / Multiplicative
Type : Univ;
Data : Type;
Prop : Data;
(A : Type : Univ) => (x : A : Type) => x;
(A : Prop : Type) => (x : A : Prop) => x;
(A : Data : Type) => (x : A : Data) => (x, x);
(A : Type) => (x : A) => x;
(A : Prop) => (x : A) => x;
(A : Data) => (x : A) => (x, x);
<A : Type>(x : A) => x;
<A : Prop>(x : A) => x;
<A : Data>(x : A) => (x, x);
<A>(x : A) => x;
<A>(x : Prop A) => x;
<A>(x : Data A) => (x, x);
Box (A : Type) : Data;
Eq<A : Type>(x : A, y : A) =
| refl : Eq(x, x);
(A : Data) => (x : A) => (eq : Eq(x, x)) : Eq(eq, refl) => _;
Eq(1, 2) : Prop;
f = (x : Nat, y : Float) -> String;
Box (A : Type) = <R>(k : (x : A) -> R) -> R;
Box<M>(A : Type) = <R>(k : (x : M A) -> R) -> R;
Box<K>(A : K) = <R : K>(k : (x : A) -> R) -> R;
(A : Type) => (x : Prop A) => x;
(A : Type) => (x : Box<Prop> Unit) => x
(x )
Type : Univ;
Data : Univ;
Prop : Univ;
Nat : Type = Prop Nat;
(x : Nat) =>
Box (T : Type) = <A>(k : T -> A) -> A;
Box<K>(T : K) : K = <A : K>(k : T -> A) -> A;
Box() : Prop
Box (Eq(1, 2)) : Prop;
Box(A : Type) : Type = <A>(k : T -> A) -> A;
(A : Type) => (x : Prop (Box A)) => x
(A : Prop) => (x : Box A) => x
(A : Type) => (x : Data Nat) => (x, x);
(+) : (x : &Nat) -> (y : &Nat) -> Nat;
(x : Data Nat) => x + x;
(x : &Nat) => (x, x);
Kind : Kind; // universes, erasable
Type : Kind; // resources, linear
Data : Kind; // data, duplicable
Prop : Kind; // propositions, irrelevant
Box (A : Type) = <K>(k : (x : A) -> K) -> K;
(A : Type) => (x : A) =>
(A : Type)
List(A : Type) : Type;
List(A : Data) : Data;
List(A : Prop) : Prop;
Squash (K : Kind) : Type = <A>(K -> A) -> A;
squash<K>(x : K) : Squash K = k => k x;
id = (A : Type) => (x : A) => x;
id (squash Type) : (x : squash Type) -> squash Type;
Eq<A : Type>(x : A, y : A) : Type;
Eq<A : Data>(x : A, y : A) : Prop;
List(A : Type) : Type;
List<K>(A : K) : K;
(x : &Nat) =>
Kind : Kind; // universes, erasable
Type : Kind; // resources, linear
Data : Kind; // data, duplicable
Prop : Kind; // propositions, irrelevant
// TODO: functions over data, can they be in Data? What about h-sets?
// TODO: functions over data also implies in automatic memory management
List(A : Type) : Type;
Double(A : Type) = (x : A, y : A)
b @-> (P : Bool -> Type) -> P true -> P false -> P b
x : Type = (A : Data) -> A;
Fix = f @=>
User : Type + Copy + Free;
(A : Type & A = Prop _) =>
Kind : Kind; // universes, erasable
Type : Kind; // resources, linear
Data : Kind; // data, duplicable
Prop : Kind; // propositions, irrelevant
// functions on data? Maybe make it predicative?
// functions on prop?
False : Type = (A : Data) -> A;
f = (A : Data) => (x : A) => x;
(A : Data) => (x : A) => x
Nat64 : Data;
Nat64.size = 8;
Pointer(mem : Memory, size : Nat64) : Data;
Pointer(mem, size) = {
addr : Nat64;
valid : addr + size < length(mem);
};
Nat128(mem : Memory) : Data;
Nat128.size : Nat64;
Nat128(mem) = Pointer(mem, Nat128.size)
Nat128.size = 16;
String(mem) : Data;
String.size(mem) : Nat64;
String(mem) = {
addr : Nat64;
valid : addr + Nat64.size + String.size(mem) < length(mem)
};
User(mem) : Data;
User(mem) = {
addr : Nat64;
valid : addr + Nat128.size + ;
};
External Message -> Check State -> Queue Message
-> Error
Queue Message -> Lock Required Data -> Compute -> Commit Change ->
T_False = Unit @-> Type;
(False : T_False) @=> f @-> (P : False -> Type) -> P f;
False : Type) @=> f @-> (P : False -> Type) -> P f;
Unit = u @-> (P : Unit -> Type) -> P unit -> P u;
@Unit : Type;
@unit : Unit;
@Unit = (u : Unit) @-> (P : Unit -> Type) -> P unit -> p u;
@unit = P => x => x;
False : (False : Type) -> Type
= (False : Type) => (f : False) @-> (P : False -> Type) -> P f;
False : Type = @tie(False);
T_False = False @-> (f : f @-> @False f) -> Type;
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = (False : T_False) @-> (f : T_f False) -> Type;
T_f False = (f : T_f False) @-> @False f;
T_False = (T_False : Type) => (T_f : (False : Type) Type) => (f : T_f) -> Type;
T_Unit = (T_Unit : Type) => (Unit : T_Unit) ->
(unit : @tie((T_unit : Type) => Unit )) -> Type;
Unit : (Unit : Type) -> (unit : Unit) -> Type
= (Unit : Type) => (unit : Unit) =>
(u : Unit) @-> (P : Unit -> Type) -> P unit -> P u;
Unit = @fix(Unit)
T_Unit = Unit @->
T_False = False @-> (f : f @-> @False f) -> Type;
((@T_False : Type) @=>
(False : T_False) @-> (f : ) -> Type);
(T_False) : Type @=>
Unit : Type;
unit : Unit;
Unit = (u : Unit) @-> (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
T_False = False @-> (f : f @-> @False f) -> Type;
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = (False : T_False) @-> (f : T_f False) -> Type;
T_f False = (f : T_f False) @-> @False f;
T_False = False @-> (I : I @-> _ -> @False I) -> Type;
@tie(T_False : Type, T_f : (False : T_False) -> Type). (
T_False1 = (False : T_False) @-> (f : T_f False) -> Type,
T_f1 (False : T_False1) = (f : T_f False) @-> @False f
)
@fix.self()
Kind : Kind; // not h-set, affine, erasable
Type : Kind; // not h-set, linear, managed manually
Data : Kind; // h-sets, intuitionistic, reference counted
Prop : Kind; // h-sets, intuitionistic, irrelevant
Bool = (A : Type) -> |A| -> |A| -> A;
clone
Fast : Kind; //
[@teika.mode.performance]
(A : Data) => (x : A) => (x.clone(), x)
id = (A : Data) => (x : A) => (x, x);
id = (A : Type) => (x : A) => x;
GC Minor + Rc Major
x = 1;
x = x + 1;
y = x + 2;
Kind : Kind; // not h-set, affine, erasable
Type : Kind; // not h-set, linear, managed manually
Data : Kind; // h-sets, intuitionistic, reference counted
Prop : Kind; // h-sets, intuitionistic, irrelevant
Γ |- A : P Γ, x : A |- B : R
-----------------------------
Γ |- (x : A) -> B : K
{ P : 'P; R : Type; K : Type }
{ P : 'P; R : Prop; K : Prop }
{ P : Type; R : Data; K : Type } // prevent linear violation
{ P : Data; R : Data; K : Data }
{ P : Prop; R : Data; K : Data }
Unit : Prop;
id = (x : Unit) => id;
Fix : Type = Fix -> Unit;
fix = x => id (x x);
id : (A : Type) -> (x : A) -> A = _;
(A : Type) => (x : A) => x
((x : A : Type) -> (B : Data)) : Type
((x : A : Prop) -> (B : Data)) : Data
((x : A : Data) -> (B : Data)) : Data
((x : A : Type) -> (B : Prop)) : Prop
(x : A : Type 0) => (A : Prop) => (x : A) => x
()
@tie()
@fix
(x : )
Type : Kind;
Data : Kind;
Prop : Kind;
Sigma A B =
s @-> (P : Sigma A B -> Type) ->
((fst : A) -> (snd : B fst) -> K) -> P s;
Prop = p @-> (P : Prop -> Type) ->
((A : Type) -> (x : A) -> (irr : (y : A) -> Eq x y) -> P _)
-> P p;
Prop = (A : Type, x : A, )
Data = (A : Type, x : Rc A);
(A : Data) => (x : fst A) => _
Kind.free<A : Kind>(x : A) : n
Unit : Type;
unit : Unit;
Unit = u @-> (P : Unit -> Type : Kind) -> P unit -> P u;
Type : Erasable Type;
Bool = (A : Type) -> A -> A -> A;
(b : Bool) => (b (@squash Type) : @squash Type -> @squash Type : Type)
(b : Bool) => (@unsquash (b (@squash Type)) : Type -> Type : Kind)
Type : Type;
Fix = Fix -> Type;
fix = x => x;
LType : LType;
IType l : IType (l + 1);
id = x => x;
fix = x => x x;
omega = fix fix;
Type : Type;
Fix = Fix -> ();
fix : |Fix| = x => x x;
(x) => x + x
Fix = Fix -> ();
Nat [a] = (K : Type) -> K -> ((b < a) -> Nat b -> K) -> K;
fold [a] = (n : Nat [a]) => K => acc => f =>
n K acc (b => pred => fold [b] pred K (f acc) f);
Type : Type;
Term [a] = (K : Type) ->
(var : String) ->
(app : [l] -> [r] -> a == 1 + l + r -> Term [l] -> Term [r] -> K) ->
(abs : [b] -> a == 1 + b -> String -> Term [b] -> K) ->
K;
Term [a] = (K : Type) ->
(var : String -> K) ->
(app : [l] -> [r] -> a == 1 + l + r -> Term [l] -> Term [r] -> K) ->
(abs : [b] -> a == 1 + b -> String -> Term [b] -> K) ->
K;
abs "x" (var "x")
(x => x)
[s_f] => [s_x] => (f : T [s_f]) => (x : _) => x y
size M = a
size N = b
M N =
app lambda arg : Term = K => app => abs => app lambda arg;
abs body : Term = K => app => abs => abs body;
id : Term = abs (x => x);
Type [α] : Type [1 + α]
// template
Γ |- n : Size Γ |- A : Type n Γ |- M : A
------------------------------------------
Γ |- M : A
// size
-----------------
Γ |- Size : USize
-------------
Γ |- 0 : Size
Γ |- n : Size
-----------------
Γ |- 1 + n : Size
// universe
Γ |- n : Size
--------------------
Γ |- Type n : Type 0
//
Γ, n : Size |- T : Type m
---------------------------------------
Γ |- (n : Size) -> T : Type (m[n := 0])
Γ, n : Size |- M : T
--------------------------------------
Γ |- (n : Size) => M : (n : Size) -> T
Γ |- M : (n : Size) -> T Γ |- N : Size
---------------------------------------
Γ |- M N : T[n := N]
//
Γ |- A : Type a Γ, x : A |- B : Type b
---------------------------------------
Γ |- (x : A) -> B : Type (1 + b)
Γ |- A : Type a Γ, x : A |- M : B
----------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- A : Type a Γ |- M : (x : A) -> B Γ |- N : A
--------------------------------------------------
Γ |- M N : B[x := N]
Nat s = (A : Type s) -> A -> (A -> A) -> A;
Fix = (x : Fix $) -> ();
fix = (x : Fix) => x [a] x;
f = (x : Nat n) : Nat (2 * n) => x + x;
fix 0 (fix 0)
Nat = (n : Size) -> (K : Type n) -> K -> (Nat -> )
(n : Size) => (A : Type n) => (x : A) => x;
Term [a] =
| Var : [a] -> String -> Term [1 + a]
| Abs : [a] -> String -> Term [a] -> Term [1 + a]
| App : [a] -> [b] -> Term [a] -> Term [b] -> Term [1 + a + b];
Type : Type;
Data : Type;
⊥ = (A : *) -> A;
¬ φ === φ -> ⊥;
℘ S === S -> Type;
U : Kind = (X : Kind) -> (℘℘X -> X) -> ℘℘X;
τ (t : ℘℘U) : U = (X : Kind) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> σ x p -> p x);
℘ S === S -> Type 0;
U : Type 2 = (X : Type 1) -> (℘℘X -> X) -> ℘℘X;
τ (t : ℘℘U) : U = (X : Type 1) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> σ x p -> p x);
U : Type 0 = (X : Type 0) -> (℘℘X -> X) -> ℘℘X;
id : ()
= s => A =>
Unit [0] = (A : Type) -> A -> A;
Unit [1 + a] = u @-> (P : Unit [b] -> Type) -> P (unit [a]) -> P (u [a]);
Id s : Type (2 + s) = (A : Type s) -> (x : A) -> A;
id s = A => x => x;
pair s : Type (2 + s + s) = (A : Type s) => x => (x, x)
Type : Type
Fix = Fix -> ();
fix = x => x x;
A => x => x
@u A x == x
Prop : Type;
Data : Type;
Type : Type;
Type : Type;
Term =
| Type
| (x : A) -> B
| (x : A) => M
| M N;
Eq<A>(x : A, y: A) = (P : A -> Type) -> P x -> P y;
Eq(Eq<Bool>(x, y), refl);
(l : List Int) -> Eq(bubble(l), quick(l));
bubble = quick
Prop :
(x : A, y : A) -> Eq(x, y);
a b -> a == b \/ a != b
(x : A : Prop) =>
f : () -> Unit;
f : (A : Prop) -> (x : A) -> x ==
Prop // single constructor
Set // equality is a mere proposition
Type
Prop : Type 0
Set : Type 0
Set : Type 0
Type 0 : Type 1
Type 0 == Type 0
(mem : Memory) =>
Int64(mem : Memory) = {
addr : Pointer;
is_valid : addr + 8 < length(mem);
};
Γ, x : @self(x). T |- Type
--------------------------
Γ |- @self(x). T : Type
Unit @=> u @-> (P : Unit -> Type) -> P (u @=> P => x => x) -> P u
!Unit = u @-> (P : @Unit I -> Type) -> P (I (u @=> P => x => x)) -> P (I u);
Unit = Unit @=> (I : I @-> !Unit -> @Unit I) => !Unit;
Unit : Type;
unit : Unit;
Unit = (u : Unit) @-> (P : Unit -> Type) -> P unit -> P u;
unit = P => x => x;
Bool : Type;
true : Bool;
false : Bool;
Bool = (b : Bool) @-> (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- M : B[x := M]
Inductive N2: Type :=
| O : N2
| S : N2 -> N2
| mod2 : S (S O) = O.
N2 : Type;
zero : N2;
succ : (pred : N2) -> N2;
mod2 : succ (succ zero) == zero;
N2 = n @-> (P : N2 -> Type) -> P zero ->
((pred : N2) -> P (succ pred)) -> P n;
zero = P => z => s => z;
succ pred = P => z => s => pred (pred => P (succ pred)) (s z) z;
mod2 = refl;
Squash : (A : Type) -> Type;
box : (A : Type) (x : A) -> Squash A;
Squash = s @-> (P : Squash A -> Type) -> ((x : A) -> P (box A x)) -> P s;
succ : (pred : Nat) -> Type;
Type -> Type l
Term =
| Type
| x
| (x [a] : A) -[b]> B
| (x : A) => M
| M N;
(x : A) -[s]> B
(A ['a]: Type) -[1]> (x ['x] : A) -['x]> A;
(A ['a]: Type) -[1]> (x ['k] : A) -> (y ['k] : A) -['k]> A;
(A ['a]: Type) => (x ['x] : A) => x
Nat = (A : Type) -> A -> (Nat -> A) -> A;
mu : (Type -> Type) -> Type;
mu = x => x x;
℘ S === S -> Type;
U : Type = (X : Type) -> (((X -> Type) -> Type) -> X) -> (X -> Type) -> Type;
Mu G = (X : Type) -> (G X -> X) -> X;
℘ S === S -> Type;
--------------
Id : Type 0 = |A : Type 0| -> (x : A) -> A;
Nat = (A : Type) -> A -> |A -> A| -> A;
U : Type 2 = (X : Type 1) -> (℘℘X -> X) -> ℘℘X;
τ (t : ℘℘U) : U = (X : Type 1) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f))); // fails as x X is invalid
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> σ x p -> p x);
Nat (Self : Type) = (A : Type) -> A -> (Self -> A) -> A;
Nat : Type = (X: Type) -> (℘℘X -> X);
unfold : Nat -> (A : Type) -> A -> (Nat -> A) -> A =
(A : Type) -> A -> ( -> A) -> A
Fix : Type;
fold : (Fix -> ()) -> Fix;
unfold : Fix -> (Fix -> ());
fold = (x : Fix -> ()) : Fix =>
// introduce abstraction
_;
unfold = (x : Fix) : (Fix -> ()) =>
// eliminate abstraction
_;
(A : Type) ->
// Type 0 implies in statically known size
((A : Type 0) -> A -> A) : Type 1;
Bool : Type 1 = ∀(l : Level). ∀(A : Type l). A -> A - A;
U : Type 1 = (X : Type 0) ->
(((X -> Type 0) -> Type 0) -> X) -> (X -> Type 0) -> Type 0;
τ (t : (U -> Type 0) -> Type 0) : U = (X : Type 0) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> σ x p -> p x);
Sigma (l : Level) (A : Type l) (B : A -> Type l) : Type (1 + l) =
s @-> (P : Sigma l A B -> Type l) ->
(k : (x : A) -> (y : B a) -> P (s @=> P => k => k x y)) -> P s;
Sigma (l : Level) (A : Type l) (B : A -> Type l) : Type (1 + l) =
s @-> (P : Sigma l A B -> Type l) ->
(k : (x : A) -> (y : B x) -> P (s @=> P => k => k x y)) -> P s;
Sigma (l : Level) (B : Level -> Type l) : Type (1 + l) =
s @-> (P : Sigma l B -> Type l) ->
(k : (x : Level) -> (y : B x) -> P (s @=> P => k => k x y)) -> P s;
fst l B pair = @pair (_ )
(A : Type l)
double = x => x + x;
does_a_for = n => {
for (let i = n; i > 0; i--) {
}
};
const loop = () => {
while (true) {}
};
const loop = () => loop();
const map = (f, l) => {
if (l.length == 0) {
return [];
}
const [el, ...tl] = l;
return [f(el), ...map(f, tl)];
};
true = (x => y => x);
false = (x => y => y);
one = z => s => s(z);
two = z => s => s(s(z));
pair x y = k => k x y;
(x => pair x x)
(x => x(x)) (x => x(x))
Array = {
create : <A>(initial : A, len : Int, len_is_nat : length >= 0) -> Array<A>
} = _;
Array.create(0, -5, loop());
f : (x : number) -> (y : number) -> number
= x => y => x + 1;
(x => x x) (x => x x)
Array = {
create : <A>(initial : A, len : Int, len_is_nat : length >= 0) -> Array<A>
} = _;
incr : (x : Int) -> Int = _;
incr : (x : Int) ->? Int = _;
Array.create(0, -5, loop());
{
"key": {
"key": {
"key": {
"key": {
"key": {
"key": {}
}
}
}
}
}
}
Type : Type;
Dynamic
Bool = (A : Type) -> A -> A -> A;
℘ S === S -> Type;
U : Type = (X : Type) -> (℘℘X -> X) -> ℘℘X;
τ (t : ℘℘U) : U = (X : Type) => (f : ℘℘X -> X) => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> σ x p -> p x);
Nat [a] @=> (A : Type) -> A -> ((b < a) -> Nat [b] -> A) -> A;
(Unit [U_a]) @=> () -> (u : Unit [b]) @->
(P : [b > a] -> Unit [c] -> Type) ->
P [U_a] unit -> P [u_a] u;
(unit [u_a]) @=> (P : [a] -> ([a = 1 + b] -> Unit [b]) -> Type)
Unit = u @-> (P : Unit -> Type) -> P unit -> P u;
Bool : Type 1 = (A : Type 0) -> A -> A -> A;
Id = (A : Type _) -> A -> A;
id = (A : Type _) => (x : A) => x;
id Id id
P => u => p_unit : P u =>
u
| unit => p_unit;
(pred : _) => (x : pred (_ => Type) Int String) =>
()
id
Nat [a] = (A : Type) -> A -> ([b < a] -> Nat [b] -> A) -> A;
Unit [0] = (u : Unit [⊥]) @-> (P : Unit [⊥] -> Type) -> P unit -> P u;
Unit [1 + a] = (u : Unit [a]) @-> (P : Unit [a] -> Type) -> P unit -> P u;
Unit [a] =
(u [b < a] : Unit [b]) @-> (P : Unit [b] -> Type) -> P unit -> P u;
T_False : [a] -> Type;
T_False [a] =
(False [b]) @->
(f : (f [b]) @-> @False f) -> Type;
False : [b < a] -> T[a := b]
[k] -> (False [a < k]) @-> (f : (f [b = 1 + a]) @-> @False [b] f) -> Type;
Unit : [k] -> (Unit [a < k]) @-> Type;
Unit = [k] => (Unit [a < k]) @=> (u [b < a]) ->
(P : Unit [b] -> Type) -> P unit -> P u;
[k] => (Nat [a < k]) @=> (n [b < a]) -> (P : Nat [b] -> Type) ->
P zero -> ((pred : Nat [b]) -> P (succ pred)) -> P n;
[k] => (Nat [a < k]) @=> (n [b < a]) -> (P : Nat [b] -> Type) ->
P zero -> ([c < a] -> (pred : Nat [c]) -> P (succ pred)) -> P n;
Term =
| Type
| (x : A) -> B
| (x : A) => M
| M N;
// naive
-----------------
Γ |- Size : USize
-------------
Γ |- 0 : Size
Γ |- a : Size
-----------------
Γ |- 1 + a : Size
// TODO: maybe this allows for some interesting elimination
Γ |- a : Size
--------------------
Γ |- Type a : Type a
Γ |- A : Type a Γ, x : A |- B : Type b
---------------------------------------
Γ |- (x : A) -> B : Type (1 + a + b) // abstraction overhead
Γ, x : Size |- B : Type b
-------------------------------------------
Γ |- (x : Size) -> B : Type (1 + b[x := 0])
// fancy
-----------------
Γ |- Size : USize
-------------
Γ |- 0 : Size
Γ |- a : Size
-----------------
Γ |- 1 + a : Size
// TODO: all inhabitants besides of the universe itself are abstractions
Γ |- a : Size
--------------------------
Γ |- Type a : Type (1 + a) // abstraction overhead
Γ |- A : Type a Γ, x : A |- B : Type b
---------------------------------------
Γ |- (x : A) -> B : Type (a + b)
Γ, x : Size |- B : Type b
---------------------------------------
Γ |- (x : Size) -> B : Type (b[x := 0])
(A : Type 0) -> (x : A) -> A : Type 1
(A : Type 1) -> (x : A) -> A : Type 4
((s : Size) -> (A : Type s) -> (x : A) -> A) : Type 1
(K : Type 0) -> (k : (A : Type 0) -> K) -> K : Type 1
(A : Type 0) -> (B : Type 0) -> A : Type 1
(s : Size) -> (K : Type s) -> (k : (A : Type s) -> K) -> K : Type 2
(s : Size) -> (A : Type s) -> (B : Type s) -> A : Type 1
Type (1 + l) == ((s : Size) -> Type (l + s))
(A : Type)
(x : Size) -> (A : Type x) -> A
(A : Type 0) -> (B : Type 0) -> A : Type 1
(s : Size) -> (U : Univ s) -> (A : U) -> (B : U) -> A : Type 1
// measuring how many sizes are unknown
Γ |- a : Size
--------------------
Γ |- Type a : Type a
(A : Type 0) ->
// Tarski
-----------------
Γ |- Size : USize
-------------
Γ |- 0 : Size
Γ |- a : Size
-----------------
Γ |- 1 + a : Size
Γ |- a : Size
--------------------------
Γ |- Univ a : Univ (1 + a) // universe overhead
Γ |- a : Size
--------------------
Γ |- Type a : Univ a
Γ |- A : K a Γ, x : A |- B : K b
------------------------------------
Γ |- (x : A) -> B : Type (1 + a + b) // abstraction overhead
Γ, x : Size |- B : Type b
------------------------------------------- // compact
Γ |- (x : Size) -> B : Type (1 + b[x := 0]) // abstraction overhead
// (A : Type 0) -> (x : A) -> A : Type 1
(s : Size) -> ()
// (A : Type 0) -> (B : Type 0) -> A : Type 1
(s : Size) -> (U : Univ s) -> (A : U) -> (B : U) -> A : Type 1
// naive
-----------------
Γ |- Size : USize
-------------
Γ |- 0 : Size
Γ |- a : Size
-----------------
Γ |- 1 + a : Size
// TODO: maybe this allows for some interesting elimination
Γ |- a : Size
--------------------
Γ |- Type a : Type a
Γ |- A : Type a Γ, x : A |- B : Type b
---------------------------------------
Γ |- (x : A) -> B : Type (1 + a + b) // abstraction overhead
Γ, a : Size |- T : Type b
---------------------------------------------
Γ |- (a : Size, x : T) : Type (1 + b[a := 0]) // indirection overhead
// (A : Type 0) -> A : Type 1
(s : Size, T : Type s) : Type 1
(s = 2, T = (A : Type 0) -> (B : Type 0) -> A) : Type 1
(s = 5, T = (A : Type 1) -> (B : Type 1) -> A) : Type 1
// naive
-----------------
Γ |- Size : USize
-------------
Γ |- ω : Size
Γ |- a : Size
------------------
Γ |- lift a : Size
Γ |- a : Size Γ |- b : Size
----------------------------
Γ |- max a b : Size
Γ |- a : Size
---------------------------
Γ |- Type a : Type (lift a)
Γ |- A : Type (b < a) Γ, x : A |- B : Type (c < a)
---------------------------------------------------
Γ |- (x : A) -> B : Type (a
Γ, [a] |- T : Type b
----------------------
Γ |- [a] -> T : Type ω
[x] -> [y < x] -> (A : Type 1) -> A
[a] =>
(x : Int) => x + 2 : (x : Int) -> Int
Id : Type 2 = (A : Type 1) -> A -> A;
Nat = (A : Type 0) -> A -> (Nat -> A) -> A;
-----------------
Γ |- Size : USize
Γ |- a : Size
------------------
Γ |- lift a : Size
Γ |- a : Size Γ |- b : Size
----------------------------
Γ |- max a b : Size
Γ, a : Size |- b : Size Γ, x : A |- B : Type
---------------------------------------------
Γ |- (x [a] : A) -[b]> B : Type
Γ, a : Size |- b : Size Γ, x : A |- B : Type
---------------------------------------------
Γ |- (x : A) -[b]> B : Type
Γ |- M : (x : A % ) -[b]> B Γ |- N : A
----------------------------------------
Γ |- M N : B[x := N] | n
Γ |- A : Type a Γ, x : A |- B : Type b
---------------------------------------
Γ |- (x : A) -> B : Type (max a b)
Γ |- n : Grade Γ, x : A |- B : Type b
--------------------------------------
Γ |- (x : A $ n) -> B : Type b
Fix = (x : Fix % 2) -> ();
fix = (x : Fix % 2) => x
Nat = n @-> (l : Level) -> (A : Type l $ 0) -> (zero : A $ 1) -> (succ : (acc : A $ 1) -> A $ l) -> A;
Id : Type = (A : Type) -> (x : A) -> A;
id : Id = (A : Type) => (x : A) => x;
id Id id
Nat : Type = (A : Type) -> A -> (A -> A) -> A;
Id : Type = (A : Type) -> (x : A % 2) -> A;
(fix) => fix fix;
Data = W @-> (T : Type, clone : (x : T) -> (l : W, r : W));
Unit : Type;
unit : Unit;
clone : (u : Unit) -> (l : Unit, r : Unit);
Unit = (A : Type) -> A -> A;
unit = A => x => x;
clone = u => u _ (unit, unit);
Unit [a] : Type;
unit [a] : Unit [1 + a];
Unit [a] = (u : (A : Type) -> A -> A, clone : [b < a] -> (l : Unit [b], r : Unit [b]));
unit [a] = (A => x => x, [b < a] => (unit [b], unit [b]));
Type l : Type (lift l);
(x : A : Type a) -> (B : Type b) : Type (max a b);
Bool : Type 0 = (A : Type ω $ 0) -> A -> A -> A;
Bool : Type 1 = (A : Type 0) -> A -> A -> A;
Bool : Type 1 = (l : Level) -> (A : Type l) -> A -> A -> A;
Bool : Type 0 = (A : Type ω) -> A -> A -> A;
Bool : Type 0 = b @-> (P : Bool -> Type ω $ 0) -> P true -> P false -> P b;
Usage tracking, grading prevents calling itself because eliminating a function requires one copy, plus the required copies from the the function itself, requiring n = n + 1 to work. Pro, can still call id with id.
Size tracking, predicativity prevents calling itself because a Type universe will never include itself, so a function can never take itself.
Why is impredicativity safe sometimes?
U = (A : Type, (A = A, A -> ()) -> ());
V = (A = U, A -> ());
V <: U;
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A : Type, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: (A = U, (A = A, A -> ()) -> ())
U -> () <: (A = U, A -> ()) -> ()
(A = U, A -> ()) <: U
constraint = ['b < 'a];
constraint = ['b = 1 + 'a];
U : Type (1 + 'a) = (A : Type 'a, (A = A, A -> ()) -> ());
V = (A : Type (1 + 'a) = U, A -> ());
V <: (A : Type 'a, (A = A, A -> ()) -> ())
(A : Type (1 + 'a) = U, A -> ()) <: (A : Type 'b, (A = A, A -> ()) -> ())
1 + 'a = 'a
Id : Type 1 = (A : Type 0) -> (x : A) -> A;
id : Id = A => x => x;
Resource : Type;
Data : Type;
Property : Type;
U # 1 + 'u = (A # 1 : Type, (A # 1 = A, A -> ()) -> ());
V # 'v = (A = U, A -> ());
(A # 1 = U, A -> ()) # 'v <: U # 1 + 'u
(A # 1 = U, A -> ()) # 'v <: (A # 1 : Type, (A = A, A -> ()) -> ()) # 1 + 'u
(A # 1 = U, A -> ()) # 'v <: (A # 1 = U, (A = A, A -> ()) -> ()) # 1 + 'u
// clash, as 'u = 'u + 1
U = (A : Type, (A = A, A -> ()) -> ());
V = (A = U, A -> ());
V <: U;
(A = U, A -> ()) <: U
erase : (A : Type, x : P A) -> (A : Type, x : P A)
Univ : Univ;
Type : Univ;
Data : Univ;
Prop : Univ;
(b : Bool : Type) -> (() -> DNat) $ 1
(b : Bool) => (() => b DNat 0 1)
Memory : {
type(mem : Memory, ptr : Pointer) : Type;
get(mem : Memory, ptr : Pointer) : type(mem, ptr);
set<A>(mem : Memory, ptr : Pointer, value : A) : Memory;
};
Rc<mem, A> = {
ptr : Pointer;
valid : Memory.length(mem) < ptr;
witness : Memory.type(mem, ptr) == A;
};
℘S == S -> Type;
U : Type = (X : Type) ->
(((X -> Type) -> Type) -> X) -> ((X -> Type) -> Type) -> X;
τ (t : ℘℘U) : U = (X : Type) => |f : ℘℘X -> X| => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> [σ x p ==> p x]);
U : Type = (X : Type) -> (℘℘X -> X) -> ℘℘X;
Ω : U = (X : Type) => |f : ℘℘X -> X| => (p : ℘X) =>
((p : ℘U) => (x : U) -> [σ x p ==> p x]) ((x : U) => p (f (x X f)));
Ω : U = (X : Type) => (f : ℘℘X -> X) => (p : ℘X) =>
(x : U) -> [x U ((x : U) => p (f (x X f))) ==> p (f (x X f))] ;
(X : Type) -> ((G X) -> X) -> X;
(X : Type) -> (((R : Type) -> R -> (X -> R) -> R) -> X) -> X;
Id : Type 0 = (A : Type 0 $ 1) -> (x : A) -> A;
Nat = (A : Type)
(l : Level, x : Type (1 + l))
type M = Int -> Int;
M = Int -> Int;
Id = (A : Type) -> (x : A) -> A;
Id = ∀A. A → A;
Id = <A>(x : A) -> A;
T = <A, B>(x : A, y : B) -> A;
U = <A, B>(x : A, y : B) -> B;
Eq A x y = (P : A -> Type) -> P x -> P y;
refl A x : Eq A x x = P => p => p;
(eq : A x x) -> Eq _ eq (refl A x)
Eq A x y = (P : A -> Type) -> P x -> P y;
refl A x : Eq A x x = P => p => p;
id = <A>(x : A) => x;
Unit = <A>(x : A) -> A;
Bool = <A, B>(x : A, y : A) -> A;
Type 0 : Type 1;
Type l : Type (1 + l);
Type ∞ : Type ∞;
((A : Type ∞) -> (x : A) -> A) : Type ∞
T = <A, B>(x : A, y : B) -> A;
U = <A, B>(x : A, y : B) -> B;
NatA = | Zero | Succ (pred : NatA);
NatB = <A>(zero : A, succ : (pred : NatB) -> A) -> A;
NatA = <A>(zero : A, succ : (acc : A) -> A) -> A;
NatB = <A>(succ : (acc : A) -> A, zero : A) -> A;
T = <A, B>(x : A, y : B) -> A;
U = <A, B>(x : A, y : B) -> B;
Type 0 : Type 1;
<A : Type 0>(x : A) -> A;
Inductive circle : Type :=
| base : circle
| loop : base == base.
(Type 0 : Type 1)
(Set : Type 0);
(Type l : Type (1 + l));
* : □ : Δ
(A : *) -> A : *
(A : *) -> (B : □) -> A : *
(A : □) -> (B : Δ) -> A : Δ
Type 0 : Type 1
Type 1 :
(B : □) -> (A : *) -> A : *
Type l : Type (1 + l);
Data l : Type (1 + l);
Prop l : Type (1 + l);
Type : Type;
Data : Type;
Prop : Type;
Type : Type;
Prop : Type;
PNever : (A : Prop) -> A;
TNever : (A : Type) -> A;
never_magic : PNever -> TNever = _;
PUnit = (A : Prop) -> (x : A) -> A;
TUnit = (A : Type) -> (x : A) -> A;
unit_magic : PUnit -> TUnit = _;
T = <A>(x : A) -> <B>(y : B) -> A;
U = <A, B>(x : A) -> (y : B) -> A;
id = (A : Prop) => (x : A) => x;
id ((A : Type) -> A)
f : (A : Type) -> (B : Prop) -> B : Prop;
(l = 2, A = Type (l + l)) : (l : Level, A : Type (1 + l + l)) : Type 2
(l = 2, A = Type l) : (l : Level, A : Type (1 + l)) : Type 2
Type l : Type (1 + l);
Data l : Type (1 + l);
Prop l : Type (1 + l);
{ A : Data l: ; x : A }
Bool : Data 2;
true : Bool;
false : Bool;
Bool = b @-> (
d : (P : Bool -> Data 1) -> P true -> P false -> P b &
t : (P : Bool -> Type 1) -> P true -> P false -> P b
);
true : Bool = (P => x => y => x & P => x => y => x);
false : Bool = (P => x => y => y & P => x => y => y);
Sigma A B = s @-> (P : Sigma A B -> Data 0) ->
(k : (x : A) -> (y : B x) -> P (exist A B x y)) -> P s;
U : Data 2 = (X : Data 1) ->
(((X -> Data 0) -> Data 0) -> X) -> ((X -> Data 0) -> Data 0) -> X;
τ (t : ℘℘U) : U = (X : Type) => |f : ℘℘X -> X| => (p : ℘X) =>
t ((x : U) => p (f (x X f)));
σ (s : U) : ℘℘U = s U τ;
Ω : U = τ ((p : ℘U) => (x : U) -> [σ x p ==> p x]);
Data : Type;
Prop : Type;
id : (A : Data) -> (x : ⇑A) -> ⇑A = _;
Unit = (A : Data) -> (x : A) -> A;
(u : Unit) => (A : Type) => (x : A) => u A x;
Unit = u @-> (P : Unit -> Data) ->
(A : Data) -> (x : A) ->
Data l : Type (1 + l);
Type l : Type (1 + l);
Id : Data = (A : Data : Type) -> (x : A : Data) -> A;
Id : Type = ⇑Id;
id = (A : Data) => (x : A) => x;
Type l : Type (1 + l); // no elimination to Data
Data l : Type (1 + l); // no universes in Data
Unit : Data 1;
unit : Unit;
Unit = u @-> (
d : (P : Unit -> Data 0) -> P unit -> P u,
T : (P : Unit -> Type 0) -> P unit -> P u
);
unit = (
d = P => x => x,
T = P => x => x,
);
S = {
A : Data;
x : A;
};
id = (A : Data) => (x : A) => x;
x = id (@squash Type)
Eq A B = (P : Data -> Data) -> P A -> P B;
⇑(A : Data) => (x : A) => x
(A : ⇑Data) => (x : ⇑~A) => x
lifted_id : (A : Type) -> (x : A) -> A = ⇑id;
// rules
// Those rules they require mutually recursive blocks to be useful
Γ, x : A |- B : Type
---------------------------
Γ |- @self(x : A). B : Type
Γ, x : A |- M : B[x := @fix(x : A). M] Γ |- A ≂ @self(x : A). B
----------------------------------------------------------------
Γ |- @fix(x : A). M : @self(x : A). B
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- @unroll M : B[x := M]
Γ, x : A |- B : Type Γ |- A ≂ @self(x : A). B
----------------------------------------------
Γ |- @self(x : A). B : Type
/*
3 general steps
Describe the type indexed by the constructors of the type
Make the type family itself
Close the family on the constructors
The following code assumes implicit unroll
*/
// shape of family
T_P_Unit : Type;
T_p_unit : (P_Unit : T_P_Unit) -> Type;
T_P_Unit = @self(P_Unit : T_P_Unit). (p_unit : T_p_unit P_Unit) -> Type;
T_p_unit P_Unit = @self(p_unit : T_p_unit P_Unit). P_Unit p_unit;
// proto Unit
P_Unit : T_Unit;
p_unit : T_p_unit P_unit;
P_Unit p_unit = @self(u : P_Unit p_unit).
(P : P_Unit p_unit -> Type) -> P p_unit -> P u;
p_unit = @fix(p_unit). P => (x : P p_unit) => x;
// closing
Unit = P_Unit p_unit;
unit : Unit = p_unit;
T_False : Type;
T_f : (False : T_False) -> Type;
= @self(f : T_False)
Unit : Type;
unit : Unit;
Unit = @self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
data Z4 : Set where
zero : Z4
suc : Z4 -> Z4
mod : suc (suc (suc (suc zero))) ≡ zero
// Those rules they require mutually recursive blocks to be useful
Γ, x : A |- B : Type
---------------------------
Γ |- @self(x : A). B : Type
Γ, x : A |- M : B[x := @fix(x : A). M] Γ |- A ≂ @self(x : A). B
----------------------------------------------------------------
Γ |- @fix(x : A). M : @self(x : A). B
Γ |- M : @self(x : A). B Γ |- A ≂ @self(x : A). B
--------------------------------------------------
Γ |- @unroll M : B[x := M]
False @-> (f : f @-> @False f) -> Type;
// induction-induction
A : Type;
B : (K : A) -> Type;
// my-stuff
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = @self(False : T_False). (f : T_f False) -> Type;
T_f False = @self(f : T_f False). @False f;
@self(False : T_False). (f : @self(). ) -> Type;
@self(A : Type, T_f : _).
(False : @self(False :)) => @False f
T_f : @self(A, T_f : ). (False : @self(False). (f : T_f) -> Type) -> Type;
T_f = @fix(T_f : _). False => @self(f : @T_f False). @False f;
@exist(T_False : Type).
@self(False :
@self(False : T_False). (f : @exist(T_f : Type). T_f) T_False).
(f : @exist(T_f : Type). @self(f : T_f). @False f) -> Type;
@both(
T_False : Type = @self(False : T_False). (f : T_f False) -> Type,
T_f : (False : T_False) -> Type = False => @self(f : T_f False). @False f
)
Γ |- T : @both(x : A = M, y : B = N)
------------------------------------
Γ |- @fst T : M[x := M | y := N]
Γ |- T : @both(x : A = M, y : B = N)
------------------------------------
Γ |- @snd T : N[x := M | y := N]
Γ, x : Type |- B : Type Γ, y : B |- M : Type Γ |- N[x := M] : B
-----------------------------------------------------------------
Γ |- @ind(x = M, y : B = N) -> Type
Γ, A : Type, x : A |- B : Type
-------------------------------
Γ |- @self(A, x : B). T : Type
@self(_, T_False : Type).
@self(False : T_False). (f : @self(T_f, f : T_f). ) -> Type;
@self(A, T_f : A -> Type).
False => @self(B, f : T_f False). _ => @False f
@self(False, f). False =>
@self(False : T_False). (f : @self(f : T_f). @False f) -> Type;
-----------------
Γ |- Self : USelf
Γ, x : @self(x). T |- T : Type
-------------------------------
Γ |- @self(x). T : Type
Γ |- M : @self(A, x). T
--------------------------
Γ |- @unroll M : T[x := M]
Γ, A : Type, x : A |- T : Type
-------------------------------------
Γ |- @self(A, x). (y : B) => T : A -> Type
False @-> (f : f @-> @False f) -> Type;
@self(T_False, False : @self(_, False : T_False). (f : )).
(f : @self(T_f, f : T_f). @False f) -> Type;
Γ, A : Type, x : A |- T : Type
------------------------------
Γ |- @self(A, x). T : Type
Unit = @self(Unit, u). (unit : Unit) -> (P : Unit -> Type) -> P unit -> P u;
False = False @-> (f : f @-> @False f) -> Type;
A : Type;
B : (x : A) -> Type;
A = @self(x : A). (f : B x) -> Type;
B False = @self(f : B x). @x f;
A : Type;
B : (x : A) -> Type;
A = _;
B x = _;
Γ, x : A |- T : Type
---------------------------
Γ |- @self(x : A). T : Type
Nat = | Zero | Succ (pred : Nat);
Unit : Type;
unit : Unit;
Unit = @self(u : Unit). (P : Unit -> Type) -> P
Γ, x : A |- T : Type
------------------------------
Γ |- @self(A, x). T : Type
Γ, A : Type, x : A |- T : Type
------------------------------
Γ |- @self(A, x). T : Type
Type : Type = _;
Data : Type = _;
Mu G = (X : Type) -> (G X -> X) -> X;
Nat_G INat = (K : Type) -> X -> (INat -> Type) -> K;
Nat X = (K : Type) -> (A : Type) -> (k : A -> K) -> (z : A) ->
(s : (k : A -> K) -> (z : A) -> (p : X) -> K) -> K;
Nat_n = (X : Type) -> (Nat X -> X) -> X;
Show : Data = {
};
T_False : Type;
T_f : (False : T_False) -> Type;
T_False = (False : T_False) @-> (f : T_f False) -> Type;
μ T. (eq : μ E. (T == μ T. (eq : E) -> _)) -> _;
@self(u : Unit).
(X : Type) -> (G X -> X) -> X;
Γ, x : A |- T : Type
---------------------------
Γ |- @self(x : A). T : Type
Γ, x |- , x : A |- T : Type
-------------------------------------
Γ |- @fix(x : A). M : @self(x : A). T
T_P_Unit : Type;
T_p_unit : (P_Unit : T_P_Unit) -> Type;
T_P_Unit = @self(P_Unit : T_P_Unit). (p_unit : T_p_unit P_Unit) -> Type;
T_p_unit P_Unit = @self(p_unit : T_p_unit P_Unit). P_Unit p_unit;
P_Unit : T_Unit;
p_unit : T_p_unit P_unit;
P_Unit p_unit = @self(u : P_Unit p_unit).
(P : P_Unit p_unit -> Type) -> P p_unit -> P u;
p_unit = @fix(p_unit). P => (x : P p_unit) => x;
Γ, x : A, y : B |- M : A Γ, x == M, y : B |- N : B
---------------------------------------------------
Γ |- { x : A, y : B, x = M, y = N } : Type
Γ, x : A, y : B |- M : A Γ, y : B[x := M] |- N : B[x := M]
------------------------------------------------------------
Γ |- (x : A, y : B, x = M, n = N) : (x : A, y : B)
Γ |- M : (x : A, y : B)
------------------------------------------------------------
Γ |- M.x : A[x := fst M][y := snd M]
Γ |- M : (x : A = , y : B)
------------------------------------------------------------
Γ |- (x, y) = M; N : T
Γ, x : A, y : B |- M : A Γ, y : B[x := M] |- N : B[x := M]
------------------------------------------------------------
Γ |- (x : A; T) : (x : A, y : B)
Γ, x : A, y : B | T) : (x : A, y : B)
Γ, x : A |- M : A Γ, x == M |- N : B
-------------------------------------
Γ |- (x : A; x = M; x) : B[x := M]
Γ, x : A |- M : A Γ, x == A |- N : Type
----------------------------------------
Γ |- (x : A; x = M; N) : Type
Γ, x : A |- M : A Γ, x == M |- N : B
------------------------------------------
Γ |- (x : A; x = M; N) : (x : A; x = M; B)
T_Unit : Type;
Unit : T_Unit;
T_Unit = (unit : Unit) -> Type;
Unit = unit =>
Unit : Type;
unit : Unit;
Unit = (u : Unit) @-> (P : Unit -> Type) -> P unit -> P u;
unit = (u : Unit) @=> P => x => x;
False : Type;
False = (f : False; f : (P : False -> Type) -> P f);
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P u) => x;
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = (Unit : T_Unit) & (unit : T_unit Unit) -> Type;
T_unit = (unit : T_unit Unit) & Unit
Γ |- M : B Γ, x == A |- M : B Γ |- A ≂ (x : A) & B
--------------------------------------------
Γ |- M : (x : A) & B
(u : Unit & (P : Unit -> Type) -> P unit -> P u)
Unit : T_Unit;
Unit = (
@Unit : (unit : T_unit Unit) -> Type;
@Unit (unit : T_unit Unit) =
)
M = (
Unit : Type;
unit : Unit;
Unit = @self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
unit = @fix(u : Unit). P => x => x;
)
M.Unit === @self(u : M.Unit). (P : M.Unit -> Type) -> P unit -> P u
T_Unit = ()
Unit : Type;
unit : Unit;
Unit = @self()
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = (Unit : T_Unit) & (unit : T_unit Unit) -> Type;
T_unit = (Unit : T_Unit) => (unit : T_unit Unit) & Unit;
Bool : Type;
true : Bool;
false : Bool;
Bool = @self(b). (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Bool : Type;
true : Bool;
false : Bool;
Bool = @self(b : Bool). (P : Bool -> Type) -> P true -> P false -> P b;
true = P => x => y => x;
false = P => x => y => y;
Bool = (b : (P : Type) -> P -> P -> P) & (P : Bool -> Type) -> P true -> P false -> P b;
true = (P : ?) => x => y => x;
M : (x : A) & B;
N : (x : A) & B;
M.0 == N.0 -> M == N;
C_Bool : Type;
c_true : C_Bool;
c_false : C_Bool;
C_Bool = (A : Type) -> A -> A -> A;
c_true = A => x => y => x;
c_false = A => x => y => y;
I_Bool : (c_b : C_Bool) -> Prop;
i_true : I_Bool c_true;
i_false : I_Bool c_false;
I_Bool c_b = (P : C_Bool -> Prop) -> P c_true -> P c_false -> P c_b;
i_true = P => x => y => x;
i_false = P => x => y => y;
Bool : Type = (c_b : C_Bool, I_Bool c_b);
true : Bool = (c_b = c_true, i_true);
false : Bool = (c_b = c_false, i_false);
Bool : Type;
true : Bool;
false : Bool;
Bool = (b : (A : Type) -> A -> A -> A &
(P : Bool -> Prop) -> P true -> P false -> P b);
true = (b = A => x => y => x,);
false = P => x => y => y;
expected : (P : Bool -> Type) -> P true -> P false -> P true
received : (P : Bool -> Type) -> P true -> P false -> P true
Type : Type;
Data : Type;
Prop : Type;
(x : Nat & x >= 5);
(x = 5 & le_refl)
(a : (x : Nat & x >= 5)) => (b : (x : Nat & x >= 5)) => (eq : fst a == fst b) =>
a == b
(A : Prop) => (x : A) => (y : A) => (refl : x == y)
Unit : Type;
unit : Unit;
Unit = (P : Unit -> Type) -> P unit -> P unit;
unit = (P : Unit -> Type) => (x : P unit) => x;
t = (False : Type) => (f : A) => (False == (P : False -> Type) -> P f) =>
(f )
False : Type;
False = <K>(k : <F>(f : F, F == (P : F -> Type) -> P f) -> K) -> K;
Unit : Type;
Unit = <K>(k : <U>(u : F, F == (P : F -> Type) -> P f) -> K) -> K;
Unit : Type;
Unit = <K>(k : <U>(u : F, F == (P : F -> Type) -> P f) -> K) -> K;
MUnit Unit unit u = (P : Unit -> Type) -> P unit -> P u;
t = (T : Type) =>
(unit : A) => (A == T unit)
(U : Type) => (u : U) => (U == (P : _ -> Type) -> P unit -> P u) =>
Bool : Set 1
true : Bool
false : Bool
Bool = ι(b : Bool). ∀(P : Bool -> Set 0). P true → P false → P b
true = λ(P : Bool -> Type). λ(then : P true). λ(else : P false). then
false = λ(P : Bool -> Type). λ(then : P true). λ(else : P false). else
False : Type;
False = <K>(k : <F>(f : F, F == (P : F -> Type) -> P f -> ()) -> K) -> K;
T_dumb : Type;
dumb : T_dumb;
T_dumb = (P : T_dumb -> Type) -> P dumb -> ();
dumb = P => x => ();
false : False;
false = k => k(dumb, refl);
P_Unit : Type;
p_unit : P_Unit;
P_Unit = (P : P_Unit -> Type) -> P p_unit -> P p_unit;
p_unit = P => x => x;
WBool : Type;
WBool = <K>(k : <Bool>(true : Bool) -> (false : Bool) ->
(ind : (b : Bool) -> (P : Bool -> Type) -> P true -> P false -> P b) ->
(ind_true : ind true == P => x => y => x) ->
(ind_false : ind false == P => x => y => y) ->
(b : Bool) -> K
K) -> K;
WBool : Type;
WBool = <K>(k :
<Bool>(true : (A : Type) -> Bool A) ->
(false : (A : Type) -> Bool A) ->
<B>(b : Bool B) ->
(ind : (P : Bool B -> Type) -> P (true B) -> P (false B) -> P b) ->
K
K) -> K;
MBool : _ -> Type;
Bool : _ -> Type;
true : _ -> Bool _;
false : _ -> Bool _;
ktrue : Bool (true true);
kfalse : Bool (false false);
Bool b = (P : Bool b -> Type) -> P (true b) -> P (false b) -> P b;
true b =
ktrue = (P : Bool ktrue -> Type) => (x : P ktrue) => (y : P kfalse) => x;
kfalse = (P : Bool ktrue -> Type) => (x : P ktrue) => (y : P kfalse) => y;
false b = (P : Bool b -> Type) => (x : P (true b)) => (y : P (false b)) => y;
T_true = Bool;
T_false = Bool;
Bool b = (P : Bool b -> Type) -> P true -> P false -> P b;
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
Bool : Type;
true : Bool;
false : Bool;
MBool : (b : Bool) -> Type;
MBool b = (P : Bool -> Type) -> P true -> P false -> P b;
Bool =
Bool b = (P : T_b -> Type) -> P (true b) -> P (false b) -> P b;
f = <B>(b : Bool B) -> (ind : (P : Type -> Type) -> P T -> P F -> P B) ->
A : Type;
B : A -> Type;
Sigma : Type;
sigma : (x : A) -> (y : B x) -> Sigma A B;
s : Sigma A B;
Sigma = A => B => (P : Sigma A B -> Type) ->
(k : (x : A) -> (y : B x) -> P (sigma A B x y)) -> P s;
sigma = A => B => x => y => P => k => k x y;
A : Type;
B : A -> Type;
f = (S : Type) => (s : S) =>
()
(fst : (s : S) -> A) =>
(snd : (s : S) -> B (fst s)) => _;
Sigma A B = s @-> (P : Sigma A B -> Type) ->
((x : A) -> (y : P x) -> P (sigma A B x y)) -> P s;
T : Type;
f (K => k => k x y)
(s => )
f = <F>(f : F) => (F == (P : F -> Type) -> P f) =>
Bool : Type;
true : Bool;
false : Bool;
Bool = (b : Bool & (P : Bool -> Type) -> P true -> P false -> P b);
M :
expected : b Type True False
received : b.x Type True False
Γ, x : A |- M : B[x := @fix(x : A). M] Γ |- A ≂ @self(x : A). B
----------------------------------------------------------------
Γ |- @fix(@(x : A)). M : @self(x : A). B
T == (P : Unit -> Type) -> P unit -> P unit
B == (P : Unit -> Type) -> P unit -> P unit
(F : Type) => (F == @self(x : F). (P : F -> Type) -> x) =>
B
---------------
M ⇐ (x : A & B);
Γ, x : A |- M : B[x := M] Γ |- A ≂ @self(x : A). B
---------------------------------------------------
Γ |- @fix(@unfold x : B). M : @self(x : A). B
Γ, x : A |- M : B[x := M] Γ |- A ≂ @self(x : A). B
---------------------------------------------------
Γ |- @fix(@fold x : B). M : @self(x : A). B
Unit : Type;
unit : Unit;
Unit = @self(u : Unit). (P : Unit -> Type) -> (x : P unit) -> P u;
unit = @fix(@unfold u). (P : Unit -> Type) => (x : P (@fold u)) => x;
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = (Unit : T_Unit & (unit : T_unit Unit) -> Type);
T_unit = (unit : T_unit Unit & Unit unit);
Unit : T_Unit;
Unit unit = (u : Unit unit & (P : Unit unit -> Type) -> P unit -> P u);
PT_unit : Type;
unit : PT_unit;
unit : T_unit Unit;
unit = (P : Unit unit -> Type) => (x : P unit) => x;
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = (P : Unit -> Type) => (x : P unit) => x;
// check
(unit : (P : Unit -> Type) -> P unit -> P unit) <: Unit
// rule
((M : A) :> T) == ((N : A) :> T)
M == N
(T_Unit : Type; T_Unit = (Unit : T_Unit))
Bool : Data 1;
true : Bool;
false : Bool;
Bool = (b : Bool & (P : Bool -> Data 0) -> P true -> P false -> P b);
true = (P : Bool -> Data 0) => (x : P true) => (y : P false) => x;
false = (P : Bool -> Data 0) => (x : P true) => (y : P false) => y;
// core
------------------------
Γ |- Type : Type
Γ, x : A |- B : Type
------------------------
Γ |- (x : A) & B : Type
Γ |- x : A |- B : Type
------------------------
Γ |- (x : A) -> M : Type
Γ, x : A |- M : B
--------------------------------
Γ |- (x : A) => M : (x : A) -> B
Γ |- M : (x : A) -> B Γ |- N :> A
----------------------------------
Γ |- M N : B[x := N]
// coercion
Γ |- M : T
-----------
Γ |- M :> T
Γ |- M :> A Γ |- M :> B[x := M]
--------------------------------
Γ |- M :> (x : A) & B
Γ |- M :> (x : A) & B
---------------------
Γ |- M :> A
Γ |- M :> (x : A) & B
---------------------
Γ |- M :> B[x := M]
// base
Γ |- M ⇒ T
-----------
Γ |- M ⇐ T
Γ |- M ⇐ T
----------------
Γ |- (M : T) ⇒ T
// universe
------------------------
Γ |- Type ⇒ Type
// forall
Γ |- A ⇐ Type Γ, x : A |- B ⇐ Type
-----------------------------------
Γ |- (x : A) -> M ⇒ Type
Γ, x : A |- M ⇐ B
--------------------------------
Γ |- x => M ⇐ (x : A) -> B
Γ |- M ⇒ (x : A) -> B Γ |- N ⇐ A
----------------------------------
Γ |- M N ⇒ B[x := N]
// intersection
Γ |- A ⇐ Type Γ, x : A |- B ⇐ Type
-----------------------------------
Γ |- (x : A) & B ⇒ Type
Γ |- M ⇐ A Γ |- M ⇐ B[x := M]
--------------------------------
Γ |- M ⇐ (x : A) & B
Γ |- M ⇒ (x : A) & B
---------------------
Γ |- M ⇐ A
Γ |- M ⇒ (x : A) & B
---------------------
Γ |- M ⇐ B[x := M]
T_Unit : Type;
T_Unit = (Unit : T_Unit) &
(unit : (T_unit : Type; (unit : T_unit) & T_Unit)) -> Type
// induction-induction
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = (Unit : T_Unit) & (unit : T_unit Unit) -> Type;
T_unit = Unit => (unit : T_unit Unit) & Unit unit;
// fixpoint
Unit : T_Unit;
Unit unit = (u : Unit unit) & (P : Unit unit -> Type) -> P unit -> P u;
// fixpoint
unit : T_unit Unit;
unit = @fix(unit : T_unit Unit). P => x => x;
Γ |- A : Type Γ, x : A |- A : Type
---------------------------------------
Γ |- (x : A; y : B; x = M; y = N; K) ⇐ (x : A) & B
Γ |- A ≡ (x : A) & B Γ, y : A |- M ⇐ B
---------------------------------------
Γ |- @fix(x). M ⇐ (x : A) & B
False : Type;
False = (f : False) & (P : False -> Type) -> P f;
T_Unit : Type;
T_Unit = (Unit : T_Unit) & (A : Type) -> (unit : ) -> Type;
Unit : Type;
Unit = (u : Unit) & (P : Unit -> Type)
(u : Unit) & (P : Unit -> Type) ->
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit = @fix(unit). P => x => y
Unit == @fix(Unit). (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
[] |- (unit : (P : Unit -> Type) -> P unit -> P unit) :> Unit
[unit : (P : Unit -> Type) -> P unit -> P unit :> Unit] |-
received : (P : Unit -> Type) -> P unit -> P unit
expected : (u : Unit) & (P : Unit -> Type) -> P unit -> P u
[unit : (P : Unit -> Type) -> P unit -> P unit :> Unit] |-
received : (P : Unit -> Type) -> P unit -> P unit
expected : (P : Unit -> Type) -> P unit -> P unit
[] |- (unit : (P : Unit -> Type) -> P unit -> P unit) :>
(u : Unit) & (P : Unit -> Type) -> P unit -> P u
P : A -> Type;
P (M : A & B) == P (N : A)
(M : A & B) == (N : A) : A
Γ |-
(x : Nat & x >= 5) => x + 1
f : () -> Nat;
x = 1;
f = () => f ();
Type 0 : Type 1
Type 1 : Type 2
id : (A : Type 0) -> (x : A) -> A
= (A : Type 0 ) => (x : A) => x;
Show = {
T : Type 0;
}
Unit : Type;
unit : Unit;
Unit = (u : Unit & (P : Unit -> Type) -> P unit -> P u);
unit = (P : Unit -> Type) => (x : P unit) => x
Γ, x : A, y : B |- M : A Γ, x : A, y : B, x == M |- N : B
Γ, x : A, y : B, x == M, y == N |- K : T
----------------------------------------------------------------------
Γ |- (x : A; y : B; x = M; y = N; K) : (x : A; y : B; x = M; y = N; T)
Γ |- M : A Γ, x == M |- K : T
------------------------------
Γ |- (x = M; K) : (x = M; T)
f : <A, B>(x : A, y : B) -> A;
g : <A, B>(x : A, y : B) -> B;
f : <A, B>(x : A, y : B) -> A;
Hot : Type;
Hot = T @-> (A : Type, eq : (B : Type) -> A =~= B -> A == B);
Set : Type;
Set = (A : Type, eq : (P : ) -> (x : A) -> -> P (eq == refl));
Unit : Type;
unit : Unit;
uip : (u : Unit) -> (eq : u == u) -> eq == refl;
SUnit : Type;
SUnit_eq : (s : SUnit) -> Type;
SUnit_refl : (s : SUnit) -> SUnit_eq s;
SUnit = s @-> (x : Unit, eq : SUnit_eq);
SUnit_eq s = e @-> (eq : s == s) ->
(P : s == s -> SUnit_eq s -> Type) -> P refl SUnit_refl -> P s e;
SUnit_refl s =
Unit : Set;
Unit = (A = unit)
Prop : Type;
Prop = T @-> (
A : Type,
eq : (x : T) -> (y : T) -> (P : T -> Type) -> P x -> P y
);
Unit : Set;
Γ, x : @self(x). T |- T : Type
------------------------------
Γ |- @self(x). T : Type
Γ, x : @self(x). T |- M : T
---------------------------------
Γ |- @fix(x) : T. M : @self(x). T
Γ |- M ⇒ @self(x). T
--------------------
Γ |- M ⇐ T[x := M]
T_Unit : Type = @self(Unit). _ -> _ -> _ -> Type;
T_unit : Type = _;
Unit : T_Unit = @fix(Unit). I0 => unit => I1 => (
Unit = @unroll Unit I0 unit I1;
I0 = @unroll I0 unit I1;
unit = @unroll Unit I1;
@self(u). (P : Unit -> T'ype) -> I0 P unit -> I0 P u
);
I0 = _;
unit : T_unit = @fix(unit). I1 =>
@fix(u). (P : Unit -> Type) => (x : P unit) => I1 P x;
unit : @self(unit). @unroll Unit unit = @fix(unit).
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = @self(Unit : T_Unit). (unit : T_unit Unit) -> Type;
T_unit = Unit => @self(unit : T_unit Unit). @unroll Unit unit;
Unit : T_Unit = @fix(Unit). unit => @self(u : @unroll Unit unit).
(P : @unroll Unit unit -> Type) -> (x : P unit) -> P u;
unit : @self(unit : T_unit Unit).
@self(u : @unroll Unit unit).
(P : @unroll Unit unit -> Type) -> (x : P (@unroll unit)) -> P u = @fix(unit).
M : @self(unit : T_unit Unit). @self(u : Unit unit).
(P : Unit unit -> Type) -> (x : P unit) -> P u
@unroll M : @self(u : Unit M). (P : Unit M -> Type) -> (x : P M) -> P u
@unroll (@unroll M) : (P : Unit M -> Type) -> (x : P M) -> P (@unroll M)
T_Unit : Type;
T_unit : (Unit : T_Unit) -> Type;
T_Unit = (Unit : T_Unit) & (unit : T_unit Unit) -> Type;
T_unit = Unit => (unit : T_unit Unit) & Unit unit;
Unit : T_Unit = @fix(Unit). unit =>
(u : Unit unit) & (P : Unit unit -> Type) -> (x : P unit) -> P u;
(unit : T_unit Unit) & (u : Unit unit) & (P : Unit unit -> Type) -> (x : P unit) -> P u ==
(unit : T_unit Unit) & (P : Unit unit -> Type) -> (x : P unit) -> P unit
(unit : T_unit Unit) & (u : Unit unit) & (P : Unit unit -> Type) -> (x : P unit) -> P u
unit : (unit : T_unit Unit) & Unit unit =
@fix(unit). (P : Unit unit -> Type) -> (x : P unit) -> P u;
Unit : Type;
unit : Unit;
Unit = @self(u : Unit). (P : Unit -> Type) -> P unit -> P u;
unit = @fix(u : Unit). (P : Unit -> Type) => (x : P unit) => x;
M : @self(a). @self(b). (P : T -> Type) -> P (@unroll a) -> P b;
Γ, x : @self(x). T |- T ⇐ Type
------------------------------
Γ |- @self(x). T ⇒ Type
Γ, x : @self(x). T |- M ⇐ T
-----------------------------
Γ |- @fix(x). M ⇐ @self(x). T
Γ |- M ⇒ ιx. T
------------------
Γ |- M ⇐ T[x := M]
M { false = _; true = _; ...R; }
(M | true => _ | false => _)
(x => M) N
(x => f (x x)) (x => f (x x))
T_Unit : Type = @self(Unit). (unit : @self(unit). Unit unit) -> Type;
Unit : T_Unit = @fix(Unit). unit =>
@self(u). (P : Unit -> Type) -> P unit -> P u;
// context
-----------
• : Context
Γ : Context x ∉ Γ Γ |- A : Type
--------------------------------- // term hypothesis
(Γ, x : A) : Context
Γ : Context x ∉ Γ Γ |- M : A
------------------------------ // unlocked equality
(Γ, x == M) : Context
Γ : Context x ∉ Γ Γ |- M : A
------------------------------ // locked equality
(Γ, [x == M]) : Context
Γ : Context
------------- // unlock all equalities
|Γ| : Context
Γ : Context _ :> x ∉ Γ Γ |- M : A Γ |- x : Type
-------------------------------------------------- // coercion hypothesis
(Γ, M :> x) : Context
// equality
// TODO: type formation may depend on equality??
// TODO: prevent kind formation from depending on equality??
Γ | Δ |- A : Type Γ | Δ |- M ⇒ Type Γ |- M ⇒ A
--------------------------------------
Γ | Δ |- M ≡ N : A
// rule
Γ : Context Γ |- A ⇒ Type Γ |- M ⇒ A
-------------------------------------- // infer
Γ |- M ⇒ A
Γ : Context Γ |- A ⇒ Type Γ |- M ⇐ A
-------------------------------------- // check
Γ |- M ⇐ A
Γ : Context Γ |- A ⇒ Type Γ |- M ⇒ S Γ |- M :> A
--------------------------------------------------- // coercion
Γ |- M :> A
// TODO: maybe both should check?
Γ : Context Δ : Context Γ |- A ⇒ Type Γ |- M ⇒ A Γ |- N ⇒ A
--------------------------------------------------------------- // equality
Γ | Δ |- M ≡ N : A
// infer
// TODO: bad notation, unlock on infer
|Γ| |- M ⇒ A
------------
Γ |- M ⇒ A
Γ |- M ⇐ A
----------------
Γ |- (M : A) ⇒ A
// check
Γ |- M ⇒ S Γ |- (M : S) :> T
-----------------------------
Γ |- M ⇐ T
Γ, [x == A], M :> x |- M ⇐ A
----------------------------
Γ, x == A |- M ⇐ x
// coercion
-----------------
Γ |- (M : A) :> A
Γ, [x == T], M :> x |- M :> T
-----------------------------
Γ, x == T; Δ; |- M :> x
-------------------
Γ, M :> x |- M :> x
// universe
----------------
Γ |- Type ⇒ Type
// functions
Γ, x : A |- B ⇐ Type
------------------------
Γ |- (x : A) -> B ⇒ Type
|Γ|, x : A |- M ⇐ B
--------------------------
Γ |- x => M ⇐ (x : A) -> B
Γ |- M ⇒ (x : A) -> B Γ |- N ⇐ A
---------------------------------
Γ |- M N ⇒ B[x := N]
// intersection
Γ, x : A |- B ⇐ Type
-----------------------
Γ |- (x : A) & B ⇒ Type
Γ |- (M : S) :> A Γ |- (M : S) :> B[x := A]
--------------------------------------------
Γ |- (M : S) :> (x : A) & B
Γ |- M ⇒ (x : A) & B
--------------------
Γ |- M ⇐ A
Γ |- M ⇒ (x : A) & B
--------------------
Γ |- M ⇐ B[x := M]
// mutual fixpoint
Γ, x : A | Δ, x == M |- K ⇒ T
-------------------------------------------
Γ | Δ |- x : A; K ⇒ T[x := x : A; x = M; x]
Γ, x : A |- K ⇒ T
-------------------------------------------
Γ | Δ |- x : A; K ⇒ T[x := x : A; x = M; x]
Γ, x : B | Δ, x == M |- K ⇒ T Γ, x : A |- x :> B
------------------------------------------------- // ?
Γ, x : A | Δ |- x : B; K ⇒ T
Γ | Δ |- A ≡ (x : A) & B
Γ, x : A | Δ |- M ⇐ B Γ, x == M | Δ |- e ⇒ T
---------------------------------------------
Γ, x : A | Δ, x == M |- x = M; K ⇒ T
Context ::= Γ | Δ
Variable ::= x | y
Term ::= M | N
Type ::= A | B
Pattern := P | Q
Constraint ::= C | D
Rule :=
| Γ |- M ⇒ A // infer type
| Γ |- M ⇐ A // check type
| Γ |- P ⇒ A; Δ // infer pattern
| Γ |- P ⇐ Q; Δ // check pattern
Γ |- M ⇒ A == Γ |- M ⇐ _x
Γ |- M ⇒ A // infer type
Γ |- M ⇐ A // check type
Γ |- P ⇒ A; Δ // infer pattern
Γ |- P ⇐ Q; Δ // check pattern
(∃_A. C); Γ |- M : _A
-------------------------------
C; Γ |- (M : B) ⇒ B; C[_A := B]
(∃_a. C); (Γ, x : _a) |- M ⇒ B
-----------------------------
Γ; C |- x => M ⇒ (x : A) -> B
Bool : Type;
true : Bool;
false : Bool;
Bool = (b : Bool) & (P : Bool -> Type) -> P true -> P false -> P b;
true = (P : Bool -> Type) => (x : P true) => (y : P false) => x;
false = P => x => y => x;
Γ |- M[x := K] ≡ N[x := K] : A[x := K]
--------------------------------------
Γ, x == K |- M ≡ N : A
Γ, [x == K], (M : S) :> T |- (M : S) :> T
-----------------------------------------
Γ, x == K |- (M : S) :> x
Γ |- (M : S) :> A Γ |- (M : S) :> B[x := A]
--------------------------------------------
Γ |- (M : S) :> (x : A) & B
T_true ≣ (P : Bool -> Type) -> P true -> P false -> P true;
Γ |- (true : T_true) :> Bool
Γ, (true : T_true) :> Bool |- (true : T_true) :>
(b : Bool) & (P : Bool -> Type) -> P true -> P false -> P b
Γ, (true : T_true) :> Bool |- (true : T_true) :>
(P : Bool -> Type) -> P true -> P false -> P true
Γ |- M[x := K] ≡ N[x := K]
-------------------------- // equality
Γ, x == K |- M ≡ N : A
[] |- (unit : (P : Unit -> Type) -> P unit -> P unit) :> Unit
(unit : (P : Unit -> Type) -> P unit -> P unit) :> Unit :: [] |-
(unit : (P : Unit -> Type) -> P unit -> P unit) :> (u : Unit) & (P : Unit -> Type) -> P unit -> P u
(unit : (P : Unit -> Type) -> P unit -> P unit) :> Unit :: [] |-
(unit : (P : Unit -> Type) -> P unit -> P unit) :> (P : Unit -> Type) -> P unit -> P unit
(x : A) => (x :> B) => _;
(x : Bool, y : Int) === (y : Int, x : Bool)
incr : Nat -> Nat;
a = 1;
incr = x => incr x;
Color : Type;
is_primary : (color : Color) -> Prop;
Color =
| Red
| Green
| Blue
| Secondary(left : Color & is_primary left, right : Color & is_primary right);
is_primary color = color == Red || color == Green || color == Blue;
// TODO: is removing those locks okay?
|Γ| |- S <: T
----------------- // subtype
Γ |- (M : S) :> T
----------------- // refl
Γ |- (M : S) :> S
// TODO: what if arrow is a variable that can be expanded by equality
Γ |- (M : S) :> T
--------------------------------------------
Γ |- (x => M : (x : A) -> S) :> (x : A) -> T
Γ, [x == K], (M : S); dirty :> T |- (M : S) :> T
-----------------------------------------
Γ, x == K |- (M : S) :> T
Γ, [x == K], (M : S); dirty :> T |- (M : S) :> T
-----------------------------------------
Γ, x == K |- (M : S) :> x
Γ |- (M : S) :> A Γ |- (M : S) :> B[x := A]
--------------------------------------------
Γ |- (M : S) :> (x : A) & B
Γ |- A ≡ B
--------------------
Γ |- M ⇐ (x : A) & B
Γ | • | • |- M ≡ N : A
---------------------- // enters equivalence
Γ |- M ≡ N : A
// expand once in each side
Γ, x == M | L, x | R |- M == N : A
---------------------------------
Γ, x == M | L | R |- x <: N : A
Γ, x == M | L | R, x |- M <: N : A
---------------------------------
Γ, x == M | L | R |- x <: N : A
// expand while one of the sides is an annotation
Γ, x == M | L, x | • |- M ≡ N : A
---------------------------------
Γ, x == M | L, x | • |- x ≡ N : A
Γ, x == N | • | R, x |- M ≡ N : A
---------------------------------
Γ, x == N | • | R, x |- M ≡ x : A
// short circuits, aka, theorems
x ∉ L x ∉ R
----------------------
Γ | R | E |- x ≡ x : A
----------------------
Γ | • | E |- x ≡ x : A
----------------------
Γ | R | • |- x ≡ x : A
incr = (x : Nat) => x + 1;
x = (
(y : A) = 1;
y + 1
);
map : <A, B>(f : (x : A) -> B, l : List<A>) -> List<B>;
incr = x => x + 1;
map = (f, l) =>
l
| [] => []
| [el, ...tl] => [f(el), ...map(f, tl)];
id : <A>(x : A) -> A
= <A>(x : A) => x;
id_inter :
(id_nat : ((x : Nat) -> Nat)) &
(id_string : ((x : String) -> String)) = id;
x : Nat = id_inter 1;
y : String = id_string "a";
(n : Nat & n != 0) => n + 1
Status =
| (tag == "valid")
| (tag == "banned", content : String);
Status =
(tag : Bool, ...(tag | true => (...) | false => (..., content : String)));
| (tag == "valid", content : ())
| (tag == "banned", content : String);
R = (...,y : Nat);
Tuple = (R : Row) => (x : Nat, ...R);
Status =
(valid : Bool, content : valid | true => () | false => String);
(x : Status) =>
x
| ("valid", ()) => 0
| ("banned", _reason) => 1;
Bool : Type;
true : Bool;
false : Bool;
Bool = (b : Bool) & (P : Bool -> Type) -> P true -> P false -> P b;
true = (P : Bool -> Type) => (x : P true) => (y : P false) => x;
false = (P : Bool -> Type) => (x : P true) => (y : P false) => y;
Nat : {
@Nat : Type;
one : Nat;
add : (n : Nat, m : Nat) -> Nat;
sub : (n : Nat, m : Nat) -> Nat;
} = {
@Nat = Int;
};
User = {
id : Nat;
name : String;
};
A = { x : Nat; } & { y : Nat };
Status =
(valid : Bool) & valid
| true => (valid == true)
| false => (valid == false, content : String);
(valid : Bool) & (valid == true)
(valid : Bool) & (valid == false, content : String)
x : (!valid : Bool) = (valid = true);
x : (x : Nat, y : Nat)
sum = (!x : Nat, !y : Nat) => x + y;
// TODO: warning
x = sum (y = 2, x = 1);
(x : Nat & x == 1) => x + 1;
Show = {
A : Data;
show : (x : A) -> String;
};
<Show_Nat : Show<Nat>> = _;
(x : Nat) => x.show();
show = <A : Show>(x : A) => x.show();
x = show<Nat, Show_Nat>(1);
id = <A : Type> =>(x : A) => x.
x : Nat = id(1);
id = (A : Type) => (x : A) => x.
x : Nat = id(Nat)(1);
Point = (<A>, x : A, y : A);
id = (<A>, x : A) => x.
x = id(1);
incr = (x : Nat) => Nat.add(x, Nat.one);
id x = x;
id(x : Nat) : Nat;
f : () -> Nat ~ IO = () : Nat => ;
(x : Nat) = (f() : Nat ~ IO);
List : {
@List(A : Data) : Data;
length<A>(l : List A) : Nat ~ IO;
length<A>(l : List A) : Nat ! IO;
length<A>(l : List A) : Nat # IO;
length : <A>(l : List A) -> Nat;
length : <A>(l : List A) -[IO]> Nat;
length : <A>(l : List A) -> Nat;
map : <A, B>(f : (x : A) -> B, l : List A) -> List B;
filter : <A>(f : (x : A) -> Bool, l : List A) -> List A;
} = _;
Type : Type;
Data : Type;
Prop : Type;
Resource : Type;
Object : Type;
Dynamic : Type;
[@teika { mode = "dynamic"; }]
x = 1;
a = x 2;
univalence : (iso : A =~= B) -> A == B;
A =~= B : Type
A == B : Prop
f : _ = _;
g = rewrite sort_into_quick_sort f;
S = <A, B>(x : A, y : B) -> A;
T = <A, B>(x : A, y : B) -> B;
A = { A : Data; x : Nat; y : String; };
B = { A : Data; y : String; x : Nat; };
C = { x : Nat; y : String; A : Data; };
(g : T) => g(2, 1);
Socket : {
@Socket : Resource;
} = _;
Id : (A : Data) -> Data = (A : Data) => A;
a : (x : Nat, y : Nat) = (
x : Nat;
y : Nat;
x = y,
y = 1,
);
A | B | ...R
f = x => (
print x : _;
)
!Nat = (
Nat : Type;
Nat = (A : Type) -> A -> (Nat -> A) -> A;
Nat
);
Nat[Nat := (A : Type) -> A -> (Nat -> A) -> A]
A = (A : Type) -> A -> (Nat -> A) -> A;
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : Unit -> Type) -> P unit -> P u;
unit : (P : Unit -> Type) -> (x : P unit) -> P unit;
unit = (P : Unit -> Type) => (x : P unit) => x;
M : Open -n ≝ (∀-x. x != n -> ftv x M == ∅)
M : Closed ≝ (∀-x. ftv x M == ∅)
// explicit substitutions
Γ, [-1 := N] |- M : Closed Γ |- N : Closed
-------------------------------------------
Γ |- M[open N] : Closed
Γ, [+n := -1] |- M : Closed
---------------------------
Γ |- M[close +n] : Open -1
// context
Γ |- N : Closed
----------------------
Γ, [-n := N] : Context
Γ, [-n := N] |- M : Open -n
---------------------------
Γ |- M : Open -n
Γ, [close +n], [open +m] |- -1 : Closed
---------------------------------------
Γ, [close +n] |- -1 : Closed
(A : Type) -> _A -> _A
(B : Type) -> B\-1 -> B\-2
(A : Type) -> B\-1 -> B\-2
(
x : A;
y = x;
x = 1;
y + 1;
)
(
x : A;
[y := x];
[x := 1];
y + 1;
)
(
μ : A;
[open -1];
[open -1]
)
incr = (x : A; x + 1);
two = incr (x = 1; );
(x : A) ->
--------
Γ, x : A | Δ, x == M |- K ⇒ T
-----------------------------
Γ | Δ |- x : A; K ⇒ T
Γ, x : A |- K ⇒ T
-------------------------------------------
Γ | Δ |- x : A; K ⇒ T[x := x : A; x = M; x]
(
x : A;
y = x;
x = 1;
y + 1;
);
(
x : A;
[y := x\-1];
[x\-2 := 1];
y\-1 + 1;
);
(
x : A;
[y := x\-1];
[skip [x := 1]];
y\-1 + 1;
);
(
x : A;
[y := x];
[x := 1];
y + 1;
)
(
x : A;
[y := x];
[skip [x := 1]];
y\-1;
)
(
x : A;
[y := x];
[|x := 1];
y\-1;
)
(
x : () -> Never;
x = () => x ();
x
)
(
x : () -> Never;
[| x := () => x ()];
x
)
x[| x := () => x ()]
(() => x ())[| x := () => x ()]
() => x[| x := () => x ()] ()
() => x[| x := () => x ()] ()
y[skip [x := 1]][y := x]
y[y := x][x := 1]
(A : Prop) => (x : A) => (y : A) => (refl : x == y)
(
x : A;
[|y := x; x := 1];
y
)
y[|y := x; x := 1]
x[|y := x; x := 1]
1[|y := x; x := 1]
Term := n | λM | M N | M[S];
Subst := M | id | S1 . S2 | fix S;
(1)[M] ~> M
(1 + n)[M] ~> n
(n)[id] ~> n
(n)[fix S] ~> (n)[S . fix S]
(1)[M . S] ~> M[S]
(1 + n)[M . S] ~> (n)[S]
(n)[id . S] ~> (n)[S]
(n)[fix S1 . S2] ~> (n)[S1 . fix S1 . S2]
(n)[M . S] ~>
(n)[fix S] ~> n[S][fix S]
(λM)[S] ~> λM[S]
(M N)[S] ~> M[S] N[S]
M[fix S1][S2]
M[s1][s2]
(
x : () -> Never;
[fix [x := () => x ()]];
x
)
(
x : Nat;
[y := x];
[|y := x; x := 1];
y
)
(A = Int; (x : A) -> A)
Γ, x == N |- M ⇐ T
-------------------
Γ |- M ⇐ (x = N; T)
M : (A : Type; A = Int; (x : A) -> A);
----------------------------
M N : (A : Type; A = Int; A)
Γ, x == M |- K : B
----------------------------
Γ |- (x = M; K) : (x = M; B)
----------------------------
Γ |- (x = M; K) ~> K[x := M]
Term = | x\+l | x\-i | x => M | M N | M[S];
Subst = | open M | close x\+n;
(x => M) N ~> M[open M] // beta
x\-1[open M] ~> M
x\-(1 + i)[open M] ~> x\-i
x\+l[close x\+n] ~> x\+l
x\+l[close x\+l] ~> x\-1
x\+l[open M] ~> x\+l
x\-i[close x\+l] ~> x\-(1 + i)
(x => M)[S] ~> x => M[open x\+l][S][close x\+l]
(M N)[S] ~> M[S] N[S]
(x => \-1 \-2)[open t]
x => (\-1 \-2)[open x\+l][open t][close x\+l]
x => \-1[open x\+l][open t][close x\+l] \-2[open x\+l][open t][close x\+l]
x => \-1 t
(x => \-1 \+3)[close +3]
x => (\-1 \+3)[open x\+l][close +3][close x\+l]
x => \-1 \-2
O(n)
O(n^2)
(x => M) N == M[x := N]
(x => x + 1) 2 == (x + 1){x := 2} == 2 + 1 == 3
(x => x + 1) 2 == (x + 1)[x := 2] == x[x := 2] + 1[x := 2] == 2 + 1
(λ\-1 + 1) 2 == (\-1 + 1)[2] == \-1[2] + 1[2] == 2 + 1
type F<A> = A -> A;
(x => M) N
Term = | x\+l | x\-i | x => M | M N | M[S];
Subst = | open M | close;
(x => M) N ~> M[open M] // beta
x\-1[open M]; l ~> M ;
x\-(1 + i)[open M]; l ~> x\-i; l
x\+l[close]; m ~> x\+l; m
x\+l[close]; l ~> x\-1; l
x\+l[open M]; m ~> x\+l; m
x\-i[close]; m ~> x\-(1 + i); m
(x => M)[S]; l ~> x => M[open x\+l][S][close]; (1 + l)
(M N)[S]; l ~> M[S] N[S]; l
0 |- x => +1[close]
Term = | x\+l | x\-i | x => M | M N | M[S];
Subst = | open M | close;
(x => M) N ~> M[open M] // beta
x\-1[open M]; l ~> M ;
x\-(1 + i)[open M]; l ~> x\-i; l
x\+l[close]; m ~> x\+l; m
x\+l[close]; l ~> x\-1; l
x\+l[open M]; m ~> x\+l; m
x\-i[close]; m ~> x\-(1 + i); m
(x => M)[S]; l ~> x => M[open x\+l][S][close]; (1 + l)
(M N)[S]; l ~> M[S] N[S]; l
M[x := y]
M[y := x]
M[3]
1 ~> 3
2 ~> 1
1 + n ~> n
M[3][s] == M
M[3][shift . 1] == M
1 ~> 2
2 ~> 3
3 ~> 1
n ~> 1 + n n > 3
M[open y][close y] == M
2[2][lift 1] == 2
1 == 2
M[-2] // -1 -> -2
[-1 := +5]
[+5 := -1]
Concrete = no meta variables
Locally closed = no shifting or open
Closed = no shifting, open or close
(f : (x : A : Prop) -> Nat) 0 == (f : (x : A : Prop) -> Nat) 1
Γ |- N[x := M]
-------------------
Γ |- x := M; N
List(A) =
| Nil
| Cons(el : A, tl : List(A));
x : List(Nat)
x = Cons(1, x)
Term : Data;
Term =
| var x
| abs (M : Term)
| app (M : Term) (N : Term);
[M] |- app (var 1) (var 1)
Context : Data;
Term(Γ : Context) : Data;
Term =
| var : <Γ>(n) -> Term(Γ :: n)
| abs : <Γ>(M : Term()) -> Term()
| app (M : Term) (N : Term)
Type : Data;
Type =
| var(binder : Nat)
| forall(body : Type);
Type : Data;
Binder : (x : Type) -> Data;
Type =
| arrow (param : Type) (body : Type)
| var (x : Type & Binder x)
| forall (body : Type)
| exists (body : Type);
Binder = x
| arrow _ _ | var _ => Never
| forall _ | exists _ => Unit;
id : Type;
id = forall (app (var id) (var id));
Type : Data;
Binder : Data;
Type =
| arrow (param : Type) (body : Type)
| var (x : Type & Binder x)
| forall (body : Type)
| exists (body : Type);
Binder = x
| arrow _ _ | var _ => Never
| forall _ | exists _ => Unit;
forall : (b : Binder) -> _;
id : Type;
id = forall (id => app (var id) (var id));
Type : Data;
Binder : Data;
Context : Data;
Valid : (Γ : Context, n : Nat) -> Prop;
get : <Γ>(n : Nat & Valid (Γ, n)) -> Binder;
Type =
| arrow (param : Type, body : Type)
| var : (x : Binder) -> Type = k => n => k (get n)
| forall (body : Type)
| exists (body : Type);
Binder = (x : Type & x
| arrow _ _ | var _ => Never
| forall _ | exists _ => Unit);
Context = List Binder;
Valid = (Γ, n) => List.length Γ > n;
get = _;
id = forall (arrow (var ))
Type : Data;
Binder : (x : Type) -> Data;
Type =
| arrow (param : Type) (body : Type)
| var (x : Type & Binder x)
| forall (body : Type)
| exists (body : Type);
Binder = x
| arrow _ _ | var _ => Never
| forall _ | exists _ => Unit;
id : Type;
id = forall (app (var id) (var id));
Type : Data;
Binder : (x : Type) -> Data;
arrow
// let
x = 1;
f = () => x;
// shadowing
x = x + 1;
// nested-let
z = (
y = x + 1;
y + 1
);
// infered function
incr = x => x + 1;
// annotated function
double = (x : Nat) => x * x;
// type alias
My_nat = Nat;
triple : (x : My_nat) -> Nat
= x => x * x * x;
// type constructor
Id = (A : Data) => A;
a : Id(Nat) = 1;
// hoisting
fib : (n : Nat) -> Nat;
fib = n =>
n
| 0 => 0
| 1 => 1
| n => fib(n - 1) + fib(n - 2);
// polymorphism
id = <A>(x : A) => x;
// properties
div = (n : Nat, m : Nat & m >= 0) => _;
checked_div = (n, m) : Option(Nat) =>
m >= 0
| true => Some(div(n, m))
| false => None;
// universes
(Type l : Type (1 + l)); // univalence
(Prop l : Type l); // irrelevance
(Data l : Type l); // UIP
(Resource l : Type l); // linear
(Object l : Type l); // subtyping
(Dynamic l : Type l); // dynamic
dup = (sock : Socket) => (sock, sock);
// modules
Nat : {
@Nat : Data;
zero : Nat;
one : Nat;
add : (n : Nat, m : Nat) -> Nat;
} = _;
incr = (n : Nat) => Nat.add(n, Nat.one);
// effects
print : (msg : String) -[IO]> () = _;
parse : (data : String) -[Error]> Nat = _;
print : (data : Nat) -> String = _;
read : (file : String) -[IO]> (data : String) = _;
write : (file : String, data : String) -[IO]> () = _;
read_incr_and_write_back = file =[IO | Error]> (
value = read(file);
value = parse(value);
value = value + 1;
write(value);
);
loop : () -[Loop]> ();
loop = () => loop();
// intersection types
Strict_nat = (n : Nat) & n >= 0;
// union types
Either = (A : Data, B : Data) =>
| (tag == "left", content : A)
| (tag == "right", content : B);
// inductive types
Bool : Data;
true : Bool;
false : Bool;
Bool = (b : Bool) & <P>(then : P true, else : P false) -> P b;
true = (then, else) => then;
false = (then, else) => else;
Resource + Sealed types
// possible future
Bool = | true | false;
Term =
| x | M[x := N]
| x => M | M N;
(x => M) N == M[x := N] // beta
x[x := M] == M
x[y := M] == x
(x => M)[x := N] == x => M
(x => M)[y := N] == x => M[y := N]
(M N)[x := K] == M[x := K] N[x := K]
Term =
| n | M[S]
| λM | M N
Subst = M | ⇑S;
(λM) N == M[N] // beta
0[M] == M
(1 + n)[M] == n
0[⇑S] == 0
(1 + n)[⇑S] == n[]
(x => M)[x := N] == x => M
(x => M)[y := N] == x => M[y := N]
(M N)[x := K] == M[x := K] N[x := K]
Term =
| x | M[x := N]
| x => M | M N;
Term =
| x | M[...(x := N)]
| x => M | M N;
----------------------- // beta
(x => M) N ~> M[x := N]
x[x := N] ~> N
x[y := N] ~> x
(x => M)[x := N] ~> x => M
(x => M)[y := N] ~> x => M[y := N]
(M N)[x := K] ~> M[x := K] N[x := K]
(M N)[x := K1][y := K2]
(M N)[x := K1; y := K2]
Term =
| n | M[S]
| λM | M N
Subst = M | ⇑S;
(λM) N == M[N] // beta
0[M] == M
(1 + n)[M] == n
0[⇑S] == 0
(1 + n)[⇑S] == n[S]
(λM)[S] == λM[⇑S]
(M N)[S] == M[S] N[S]
_ x == x + 1
_ x == (y => y + 1) x == _k[y := x] == x + 1
_k[y := x] == x + 1
_k[y := x][x := y] == (x + 1)[x := y]
_k == y + 1
(y => y + 1) x == (y + 1)[y := x] == x + 1
Term =
| n | M[S]
| λM | M N
Subst = M | ⇑S;
(λM) N == M[N] // beta
0[M] == M
(1 + n)[M] == n
0[⇑S] == 0
(1 + n)[⇑S] == n[S]
(λM)[S] == λM[⇑S]
(M N)[S] == M[S] N[S]
Term =
| x | M[x := N]
| x => M | M N;
(x => M) N == M[x := N] // beta
M[x := N] == M{x := N}
Term =
| x | _X
| x => M | M N
| M[x := N];
(x => M) N == M[x := N] // beta
M[x := N] == M{x := N} fm(M) == ∅
M[x := N] == M{x := N}[[x := N]] fm(M) != ∅
x[x := M] == M
_X[x := M] == _X
(x => M)[y := N] == x => M[y := N]
(M N)[x := K] == M[x := K] N[x := K]
f = x => x + 1;
f 1
Term =
| n | M[S]
| λM | M N
Subst = M | ⇑S;
(λM) N == M[N] // beta
0[M] == M
(1 + n)[M] == n
0[⇑S] == 0
(1 + n)[⇑S] == n[S]
(λM)[S] == λM[⇑S]
(M N)[S] == M[S] N[S]
Term (M, N) = x | x => M | M N;
(x => M) N |-> M{x := N} // beta
Term (M, N) = x | x => M | M N | M[x := N];
(x => M) N |-> M[x := N] // beta
x[x := N] |-> N
(x => M)[y := N] |-> x => M[y := N]
(M N)[x := K] |-> M[x := K] N[x := K]
L = _ | L[x := M]
C = Term with single hole
(let x = M in _)<x + 1>
L<x => M> N == L<M[x := N]>
L<x => M> N == L<M[x := N]>
(x => M)[...(x := _)] N
(x => x + x) 1
(x + x)[x := 1]
(_ + x)[x][x := 1]
(_ + x)[1][x := 1]
(1 + x)[x := 1]
(1 + _)[x := 1]
(1 + 1)[x := 1]
(1 + 1)
Term (M, N) = _ | x | x => M | M N | M[x := N]
L = _ | L[x := M]
C = Term with single hole
// rewrite
L<x => M> N |-> L<M[x := N]> // dB
C<x>[x := M] |-> C<M>[x := M] // ls
M[x := N] |-> M if x ∉ M // gc
// plug
_<M> == M
(x => C)<M> == x => C<M>
(C N)<M> == C<M> N
(N C)<M> == N C<M>
(C[x := N])<M> == C<M>[x := N]
(N[x := C])<M> == N<[x := C<M>]>
// equiv
(y => M)[x := N] == y => M[x := N] if y ∉ fv(N)
(M N)[x := K] == M[x := K] N if x ∉ fv(N)
M[x := N][y := K] == M[x := K][x := N] if y ∉ fv(N) && x ∉ fv(K)
(x => x + x) 1
(x + x)[x := 1]
(_ + x)<x>[x := 1]
(_ + x)<1>[x := 1]
(1 + x)[x := 1]
(1 + _)<x>[x := 1]
(1 + 1)[x := 1]
(1 + 1)
Term (M, N) = _ | n | λM | M N | M[N] | M[↑]
L<K> = K | L<K>[M]
C = Term with single hole
// rewrite
L<λM> N |-> L<N[M]> // dB
C<0>[M] |-> C<M[↑]>[M] // ls
M[x] |-> M{↓} <=< 0 ∉ fv(M) // gc
// plug
_<M> == M
(λC)<M> == λC<↑M>
(C N)<M> == C<M> N
(N C)<M> == N C<M>
C[N]<M> == C<M[↑]>[N]
N[C]<M> == N[C<M>]
// example
(λλ0 1) 1 0
(λλ0 1) x f
(λ0 1)[x] f
- // ls
(λ0 _)<0>[x] f
(λ0 _)<↑x>[x] f
(λ0 ↑↑x)[x] f
(λ0 ↑x) f
(0 ↑x)[f]
(_ ↑x)<0>[f]
(_ ↑x)<↑f>[f]
(↑f ↑x)[f]
(f x)
- // dB
(0 1)[f][x]
(_ 1)<0>[f][x]
(_ 1)<f>[f][x]
(f 1)[f][x]
-- // ls
-- // gc
(↑f 1)[f][x]
(f 0)[x]
(f _)<0>[x]
(f _)<x>[x]
(f ↑x)[x]
(f x)
(f ⇑x)[x]
(f ⇑x)
(λλ0 1) 1 f
(λ0 1)[1] f
- // ls
(λ0 _)<0>[1] f
(λ0 _)<1>[1] f
(λ0 2)[1] f
(λ0 1) f ;; g
(0 ⇑x)[f]
(_ ⇑x)<0>[f]
(_ ⇑x)<f>[f]
(f ⇑x)[f]
(f ⇑x)
(λ0 1)[x] f
(_ 1)<0>[x][f]
(_ 1)<0>[x][f]
(x = 1) >=> x + 1
(x + 1) <=< (x = 1)
(x = 1>; x + 1)
(x + 1<; x = 1)
Term (M, N) = x | x => M | M N | M[x := N];
L<K> = K | L[x := M]
C<K> = K | x => C | C N | M C | C[x := N] | M[x := C]
L<x => M> N |-> L<M[x := N]> // dB
C<x>[x := M] |-> C<M>[x := M] // ls
M[x := M] |-> M <=< x ∉ fv(M) // gc
(M N)[x := K] == M[x := K] N[x := K]
M[x := y][y := x] == M[x := y[y := x]; y := x]
[x := K] |- M N
[x := K] |- M
[x := K] |- N
(x => y => M) N K
(y => M)[x := N] K
L<K> = K[x := N]
L<y => M> K
L<M[y := K]>
M[y := K][x := N]
(x + y)[y := K][x := N]
(x + _)<y>[y := K][x := N]
(x + _)<K>[y := K][x := N]
(x + K)[y := K][x := N]
(x + K)[x := N]
(_ + K)<x>[x := N]
(_ + K)<N>[x := N]
(N + K)[x := N]
(N + K)
_<x + y>[y := K][x := N]
_<>
(_ + x)<x>[x := N]
(_ + x)<N>[x := N]
(N + x)[x := N]
(N + _)<N>[x := N]
(N + N)[x := N]
(N + N)
(x x y)[y := K][x := N]
_<x x y>[x := N][y := K]
(_ y)<x x>[x := N][y := K]
(_ y)<_ x><x>[x := N][y := K]
(_ y)<_ x><N>[x := N][y := K]
(_ y)<N x>[x := N][y := K]
(_ y)<N _><x>[x := N][y := K]
(_ y)<N _><N>[x := N][y := K]
(_ y)<N N>[x := N][y := K]
(N N _)<y>[x := N][y := K]
L<K<M>> vs L<K>
L[x := N]<K<x>> |-> K<N> // fast
L[x := N]<K<x>> |-> L[x := N]<K<N>> // use
L<K<x => M>> |-> L<K<x => _><M>>
L<K<M N>> |-> L<K<_ N><M>>
L<K<_ N><M>> |-> L<K<M _><N>>
// plugging
_<M> |-> M
(x => C)<M> |-> x => C<M>
(C N)<M> |-> C<M> N
(M C)<N> |-> M C<N>
C[x := N]<M> |-> C<M>[x := N]
M[x := C]<N> |-> M[x := C<N>]
Term (M, N) = x | x => M | M N | M[x := N];
L<K> = K | L[x := M]
C<K> = K | x => C | C N | M C | C[x := N] | M[x := C]
L<x => M> N |-> L<M[x := N]> // dB
C<x>[x := M] |-> C<M>[x := M] // ls
M[x := M] |-> M <=< x ∉ fv(M) // gc
L<K<x>>[x := N] |-> L<>
L<K<x => M>> |-> L<K<x => _><M>>
L<K<M N>> |-> L<K<_2 _1><N><M>>>
L, x := N |- x :: K
-------------------
L, x := N |- K<N>
L |- x => x :: _
L |- x :: x => _ :: _
L<_1<x => x>>
L<_1<x => _1><x>>>
L<K<M>> vs L<K>
K<x x>[x := N]
K<_ x><x>[x := N]
K<_ x><N>[x := N]
K<N x>[x := N]
K<N _><x>[x := N]
K<N _><N>[x := N]
K<N N>[x := N]
M :: K == K<M>
(x x :: K)[x := N]
(x :: _ x :: K)[x := N]
(N :: _ x :: K)[x := N] // ls
(N x :: K)[x := N]
(x :: N _ :: K)[x := N]
(N N :: K)[x := N] // ls
(K<N N>)[x := N]
K<_ x><N>[x := N]
K<N x>[x := N]
K<N _><x>[x := N]
K<N _><N>[x := N]
K<N N>[x := N]
L<K<x>>[x := N] |-> L<K<N>>[x := N] // ls
L
K<_ x><N>[x := N]
L<K<(x => M) N>> |-> L<K<M[x := N]>> // dB
L<K<x => M>> |-> L<(x => _)<x>>
L<K<M N>> |-> L<K<M N>>
Γ |- M N :: K |-> Γ |- M :: _ N :: K // Lapp
Γ |- M N :: K |-> Γ |- N :: M _ :: K // Rapp
Γ |- M :: _ N :: K bv(Γ) ∩ fv(M) != ∅ // TODO: this is bad
-------------------------------------- // left-apply
Γ |- M N :: K
Γ |- M :: M _ :: K bv(Γ) ∩ fv(M) == ∅
-------------------------------------- // right-apply
Γ |- M N :: K
Term (M, N) = x | x => M | M N | M[x := N];
L |- _ = _ | L[x := M]
_ :: C = _ | x => C | C N | M C | C[x := N] | M[x := C]
----------------------------------
L |- (x => M) N |-> L |- M[x := N] // dB
-------------------------------------
(x :: C)[x := M] |-> (M :: C)[x := M] // ls
x ∉ fv(M)
--------------- // gc
M[x := M] |-> M
// plugging
M :: _ == M
M :: (x => C) == x => (M :: C)
M :: C N == (M :: C) N
M :: N C == N (M :: C)
M :: C[x := N] == (M :: C)[x := N]
M :: N[x := C] == M[x := (N :: C)]
// algorithm
-------------------------------------------- // ls
L, x := N |- x :: K |-> L, x := N |-> N :: K
(x x)[x := y][y := z]
// reference
Term (M, N) = x | x => M | M N | M[x := N];
L<K> = K | L[x := M]
C<K> = K | x => C | C N | M C | C[x := N] | M[x := C]
L<x => M> N |-> L<M[x := N]> // dB
C<x>[x := M] |-> C<M>[x := M] // ls
M[x := M] |-> M <=< x ∉ fv(M) // gc
// alternative
C<x>[x := M] |-> C[x := M]<M> // ls
C<M>[x := N] == C[x := N]<M>
// de-bruijin
Term (M, N) = _ | n | λM | M N | M[N] | M[↑];
Partial (_ :: C) = _ | λC | C N | M C | C[N] | M[C] | C[↑];
Context (L |- _) = _ | L, N;
// rewrite
L |- (λM) N :: K |-> L, N |- M :: K[↑] // dB
L, N |- 0 :: K |-> L |- N :: K[N] // ls
L, N |- K[↑] |-> L |-> K // drop
// notation
L |- K[N] == L, N |- K
// plug
M :: _ == M
M :: λK == λ(M[↑] :: K)
M :: K N == (M :: K) N
M :: N K == N (M :: K)
M :: K[N] == (M[↑] :: K)[N]
M :: N[K] == N[M :: K]
// de-bruijin
Term (M, N) = 0 | λM | M N | M[N] | M[↑];
Partial (_ :: C) = _ | λC | C N | M C | C[N] | M[C] | C[↑];
Context (L |- _) = _ | L, N;
// rewrite
L |- (λM) N :: K |-> L, N |- M :: K[↑] // dB
L, N |- 0 :: K |-> L |- N :: K[N] // ls
// equiv?
L |- M[N] :: K == L, N |- M :: K[↑]
L, N |- M[↑] :: K == L |- M :: K[N]
// plug
M :: _ == M
M :: λK == λ(M :: K)
M :: K N == (M :: K) N
M :: N K == N (M :: K)
M :: K[N] == (M :: K)[N]
M :: N[K] == N[M :: K]
L |- λM == L, 0 |- M :: λ_[↑];
L |- λ(M 0) == L, 0 |- M 0 :: λ_[↑];
x |- 1 0 :: λ_
(λ1 0)
1 0 :: λ_
M == 1
L == x
0 == 0
(1 + n) == 1[↑]
x, 0 |- 1 0 :: λ_[↑]
x, 0 |- 1 0 :: λ_[↑]
x, 0 |- 1 0 :: λ_[↑]
x, 0 |- 1 :: _ 0 :: λ_[↑]
x, 0 |- 0[↑] :: _ 0 :: λ_[↑]
x |- 0 :: (_ 0)[0] :: λ_[↑]
x |- x :: (_ 0 :: λ_[↑])[0]
x |- (x 0)[0] :: λ_[↑]
x, 0 |- (x 0) :: λ_[↑]
0[↑] ==
Term (M, N) = 0 | λM | M N | M[N] | M[↑];
Partial (_ :: C) = _ | λC | C N | M C | C[N] | M[C] | C[↑];
Context (Γ |- _) = _ | L, N;
Γ |- M[S] :: K |-> Γ, S |- M :: K
C<x>[x := M] |-> C<M>[x := M] // ls
Γ, N |- 0 :: K |-> Γ, N |- N :: K // ls
(1 + n) == n[↑]
A, B |- 1 :: K == A |- 0 :: _[↑] :: K[B]
(λM) == λ
A |- A :: _[↑] :: K[B]
A, B |- A[↑] :: K
Γ, N |- 1 + n :: K == Γ |- n :: (1 + _) :: K[N]
(1 + n :: _)[N] == (n :: 1 + _ :: _)[N]
M :: K[N] == (M :: K)[N]
(1 + n :: _)[N] == (n :: 1 + _ :: _[N])
(1 + n :: K)[N] == (n :: 1 + _ :: K)[N]
(λ_)<0>[0]
(λ_)<0>[0]
(λM)[N] == λ(M[0][N])
(λx (1 2))[0 1][1]
\0[\0 + 1]
(x + 1)[x := x + 1]
K<0[N]> == K<_<0>[N]>
K<M[S]> == K<_[S]><M>
(_ N)<M[S]> == M[S] N
(_ N)<M>[S]
M[↑][S]
M´
C<A>
M (_<N> _)<K>
Γ, x |- M |-> K
----------------------
Γ |- x => M |-> x => K
Γ, x := 1 |- 1 == x : Nat
--------------------------
Γ |- 1 == (x => x) 1 : Nat
Γ, 1 |- 1 == 0 : Nat
---------------------
Γ |- 1 == (λ0) 1 : Nat
Γ |-
---------------------------
Γ |- (λ0) 2 == (λ0) 1 : Nat
0[1]
Unit : Type;
Unit = (u : Unit);
x[x := N][x := K]
Pack : {
Unit : Type;
unit : Unit;
};
Pack = {
Unit = (u : Pack.Unit) & (P : Pack.Unit -> Type) -> P (Pack.unit) -> P u;
unit =
}
Unit : Type;
unit : Unit;
{ x : A; x : A; }
{ x : A; ...R }
Type l : Type (1 + l);
Data l : Data (1 + l);
Prop l : Prop (1 + l);
N == M : Prop
N =~= M : Type
A : Data;
((x : A) -> A) : Data
((x : A) -> A) : Type
id = (A : Type) => (x : A) => x;
x = id ((x : Nat) -> Nat)
x - 2 = 0
x = y
f(x) = f(y)
f(x) = 0;
0 = 1
0 * 0 = 1 * 0
0 = 0
x - 2 * 0 = 0 * 0
H === False == (P : (f : False) -> Type) -> P f
H |- False == @box((P : (f : False) -> Type) -> P f)
|- @box((P : (f : False) -> Type) -> P f) == @box((P : (f : False) -> Type) -> P f)
+P1 |- False == (P : False -> Type) -> P f
-P1 |- False == (P : False -> Type) -> P f
H === False == (P : (f : False) -> Type) -> P f
H |- False == (P : (f : False) -> Type) -> P f
[H] |- False == (P : (f : False) -> Type) -> P f
Γ, x : A === M | Δ |- M == N
----------------------------
Γ, x : A == M | Δ |- x == N
Γ | Δ, x : A === N |- M == N
----------------------------
Γ | Δ, x : A == N |- M == x
M === N
----------------------------
Γ, x : A === M | Δ |- x == N
M === N
----------------------------
Γ, x : A === M | Δ |- x == N
------------------------
Γ, x : A === M |- x == N
False == (P : False -> Type) -> P f |-
False ==
P | P |- (P : False -> Type) -> P f == (P : False -> Type) -> P f
H |- (P : False -> Type) -> P f == False
• | False |- False == False
id
: (A : Type) -> (x : A) -> A
= (A : Type) => (x : A) => x;
x = id String "a";
Type l : Type (1 + l);
Data l : Type (1 + l);
Prop l : Type (1 + l);
(x : Int) => x
(x : String) => x
Γ |- M == N : B
------------------------------------
Γ |- x => M == x => N : (x : A) -> B
Γ, x : A == M | R, x | • |- M == N[x := M]
------------------------------------------
Γ, x : A == M | R, x | • |- x == N
H === x == () -> x
H | x | • |- x == () -> x
H | x | • |- () -> x == () -> x
H | x | • |- x == x
H | -x, +x | +x, -x |- x == () -> x
H | +x, -x | +x, -x |- () -> x == () -> x
H | x | x |- () -> x == () -> x
Γ, x == N |- M ⇐ A
------------------
Γ |- M ⇐ A[x := N]
-------------------------------------------------
Γ |- M[x := N] : A[x := N] === Γ, x := N |- M : A
Context (Γ, Δ)
Term (M, N)
Type (A, B)
Γ |- M ⇒ (x : A) -> B Γ |- N ⇐ A
--------------------------------- // apply
Γ |- M N ⇒ B[x := N]
Γ |- M ⇒ L<(x : A) -> B> Γ |- N ⇐ L<A>tttw
--------------------------------------- // apply at a distance
Γ |- M N ⇒ L<x = N; B>
Γ, x : A[Δ] |- M ⇐ B[Δ]
------------------------------- // d-lambda
Γ |- x => M ⇐ ((x : A) -> B)[Δ]
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
----------------------------------------- // apply at a distance
Γ |- M N ⇒ B[x := N][Δ]
((x : A) -> B)[Δ]
((x : A[y := y]) -> B[y := y])[y := K]
((x : A[y := K]) -> B[y := y])[y := K]
((x : A[y := K]) -> B[y := K])[y := K]
x + 1 -| Δ
(x, y) = (1, 2); N
_<x>[x := x]
n + m == add n m
Γ |- M[x := K] == N[x := K]
---------------------------
Γ, x == K |- M == N
x == 1;
x == 1 |- 2 == x + 1
|- 2 == 1 + 1
|- 2 == 2
Γ |- _
Γ; _e
C<x>[x := N] |-> C<N>[x := N]
C<0>[N] |-> C<N>[N]
Γ, x : A |- M ⇐ B
-------------------------- // lambda
Γ |- x => M ⇐ (x : A) -> B
Γ, x : A[L] |- M ⇐ B[L]
------------------------------- // d-lambda
Γ |- x => M ⇐ ((x : A) -> B)[L]
------------------------------- // d-lambda
((x : A) -> B)[L] === ()
(X = Nat; (x : X) -> Nat) == (x : Nat) -> Nat
incr : (X = Nat; Y = Nat; (x : X) -> Y)
= (x : (X =)) => x + 1;
context : []
expected : Nat
received : (X = Nat; X)
context : []
expected : Nat
received : Nat
(x => M) N |-> M[x := N] // beta
(x => M) N |-> (x = N; M) // beta
L<x => M> N |-> L<M[x := N]> // dB
C<x>[x := N] |-> C<N>[x := N] // ls
Γ, A[Δ] |- M ⇐ B[⇑Δ]
-------------------- // bad-lambda
Γ |- λM ⇐ (∀A. B)[Δ]
Γ |- M[0 : A[Δ]] ⇐ B[0 : A . Δ]
-------------------------------- // d-lambda
Γ |- λM ⇐ (∀A. B)[Δ]
Γ |- M[0 : A . Δ] ⇐ B[0 : A . Φ]
-------------------------------- // d-lambda
Γ |- (λM)[Δ] ⇐ (∀A. B)[Φ]
M[0 : A . Δ] ⇐ B[0 : A . Φ]
--------------------------- // d-lambda
(λM)[Δ] ⇐ (∀A. B)[Φ]
(∀A. B)[Δ] == (∀A[Δ]. B[0 : A . Δ])
(∀A[Δ]. B[⇑Δ])
((x : A) -> B)[Δ]
((x : A[Δ]) -> B[0 : A][Δ])[Δ]
(λ(0 == 1))[N]
(λ(0 == 1)[N])
(λ(0 == 1[N]))
----------------
Γ |- L<M> ⇐ Δ<A>
L<((x : A) -> B)> == ((x : L<A>) -> L<B>)
((x : A) -> B)[S] == (x : A[S]) -> B[⇑S]
LC <==> LSC <==> TM
(y = K; (x => M)) N |-> (y = K; x = N; M)
(x => M) N |-> (x = N; M)
(x => x + 1) 2 |-> 2 + 1
M[Γ] ⇐ A[Γ]
----------------- // i-annot
(M : A)[Γ] ⇒ A[Γ]
M[Γ] ⇒ A[Δ] A[Δ] ≡ B[Φ]
------------------------ // dc-infer
M[Γ] ⇐ B[Φ]
----------------- // i-univ
Type[Γ] ⇒ Type[Γ]
B[x : A][Γ] ⇒ Type[Γ]
--------------------------- // i-forall
((x : A) -> B)[Γ] ⇒ Type[Γ]
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ]
------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
M[Γ] ⇒ ((x : A) -> B)[Δ] N[Γ] ⇐ A[Δ]
------------------------------------- // di-apply
(M N)[Γ] ⇒ B[x : A = N][Δ]
N[Γ] ⇒ A[Δ] M[x : A[Δ] = N][Γ] ⇒ B[Φ]
-------------------------------------- // di-let
(x = N; M)[Γ] ⇒ B[Φ]
N[Γ] ⇒ A[Δ] M[x : A[Δ] = N][Γ] ⇒ B[Φ]
-------------------------------------- // di-let
(x = N; M)[Γ] ⇒ B[Φ]
Γ |- M ⇒ A === M[Γ] ⇒ A[Γ]
Γ |- M ⇐ A === M[Γ] ⇐ A[Γ]
Γ |- M ⇐ A
---------------- // i-annot
Γ |- (M : A) ⇒ A
Γ |- M ⇒ A
---------- // dc-infer
Γ |- M ⇐ A
Γ |- N ⇒ A Γ, x : A = N |- M ⇒ B
--------------------------------- // i-let
Γ |- M[x = N] ⇒ B
Γ |- N ⇒ A Γ, x : A = N |- M ⇐ B
--------------------------------- // c-let
Γ |- M[x = N] ⇐ B
------------------- // i-univ
Γ |- Type ⇒ Type
Γ, [x : A] |- B ⇒ Type
------------------------ // i-forall
Γ |- (x : A) -> B ⇒ Type
Γ, [x : A] |- M ⇒ B
-------------------------------- // i-lambda
Γ |- (x : A) => M ⇒ (x : A) -> B
Γ |- M[x : A[Φ]][Δ] ⇐ B[x : A][Φ]
------------------------------------ // dc-lambda
Γ |- (x => M)[Δ] ⇐ ((x : A) -> B)[Φ]
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
----------------------------------------- // di-apply
Γ |- M N ⇒ B[x : A = N][Δ]
M[x : A[Φ]][Δ][Γ] ⇐ B[x : A][Φ][Γ]
------------------------------------- // dc-lambda
(x => M)[Δ][Γ] ⇐ ((x : A) -> B)[Φ][Γ]
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ]
------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
M[x : A[Φ][Γ]][Δ][Γ] ⇐ B[x : A][Φ][Γ]
------------------------------------- // dc-lambda
(x => M)[Δ][Γ] ⇐ ((x : A) -> B)[Φ][Γ]
M[x : A[Φ][+|Δ|]][Δ][Γ] ⇐ B[x : A][Φ][Γ]
------------------------------------- // dc-lambda
(x => M)[Δ][Γ] ⇐ ((x : A) -> B)[Φ][Γ]
M[x : A[⇒]][Δ][Γ] ⇐ B[x : A][Φ][Γ]
------------------------------------- // dc-lambda
(x => M)[Δ][Γ] ⇐ ((x : A) -> B)[Φ][Γ]
Γ |- M[x : A[Φ]][Δ] ⇐ B[x : A][Φ]
--------------------------------------- // dc-lambda
Γ |- (x => M)[Δ] ⇐ ((x : A) -> B)[Φ]
Γ, Δ |- M[↑|Δ|] ⇐ A
------------------- // dc-lambda
Γ |- M ⇐ A[Δ]
Γ, Δ |- M[↑|Δ|] ⇐ A
------------------- // dc-lambda
Γ |- M ⇐ A[Δ]
Γ, x : A |- M[⇑Δ] ⇐ B
------------------------------- // dc-lambda
Γ |- (x => M)[Δ] ⇐ (x : A) -> B
M[⇑Δ][x : A . Γ] ⇐ B[x : A . Γ]
------------------------------- // dc-lambda
(x => M)[Δ][Γ] ⇐ ((x : A) -> B)[Γ]
Γ, x : A[Δ] |- M ⇐ B[x : A][Δ][↑]
--------------------------------- // dc-lambda
Γ |- x => M ⇐ ((x : A) -> B)[Δ]
Γ, x : A[Δ] |- M ⇐ B[x : A][Δ][↑]
--------------------------------- // dc-lambda
Γ |- x => M ⇐ ((x : A) -> B)[Δ]
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ][↑][x : A[Δ]][Γ]
-------------------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ][Γ]
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ][Γ]
---------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ][Γ]
Γ |- N ⇒ A Γ, x : A == N |- M ⇐ B[↑]
------------------------------------- // c-let
Γ |- x = N; M ⇐ B
Γ |- M ⇐ A [0]
---------------- // c-let
Γ |- (M : A) ⇒ A
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ]
------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
Context (Γ, Δ) := _ | Γ[x : A] | Γ[x : A := N];
Term (M, N)
Type (A, B) :=
| (M : A) | Type | \n | x = N; M | x = N; M
| (x : A) -> B | (x : A) => M | M N | x => M;
Γ |- M ⇒ A === M[Γ] ⇒ A[Γ]
Γ |- M ⇐ A[Δ] === M[Γ] ⇐ A[Δ][Γ]
Γ |- M[Φ] ≡ N[Δ] === M[Φ][Γ] ≡ N[Δ][Γ]
Γ |- M ⇒ A Γ |- A[•] ≡ B[Δ] Γ |- (M : A) ⇐ A[•]
---------------------------- -------------------
Γ |- M ⇐ B[Δ] Γ |- (M : A) ⇒ A
----------------
Γ |- Type ⇒ Type
Γ |- \n ⇒ B
------------------ ------------------------
Γ[x : A] |- \0 ⇒ A Γ[x : A] |- \(1 + n) ⇒ B
Γ[x : A] |- B ⇒ Type[Δ] Γ[x : A] |- M ⇒ B[Δ]
--------------------------- -----------------------------------
Γ |- (x : A) -> B ⇒ Type[Δ] Γ |- (x : A) => M ⇒ (x : A) -> B[Δ]
Γ[x : A[Δ]] |- M ⇐ B[y : A][Δ][↑]
--------------------------------- // dc-lambda
Γ |- x => M ⇐ ((y : A) -> B)[Δ]
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
----------------------------------------- // di-apply
Γ |- M N ⇒ B[x : A := N][Δ]
Γ |- N ⇒ A[Δ] Γ[x : A[Δ] == N] |- M ⇒ B[Φ]
------------------------------------------- // dr-let-infer
Γ |- x = N; M ⇒ B[Φ][x : A[Δ] == N]
Γ |- N ⇒ A[Δ]
---------------------------------- // dr-let-infer
Γ |- x = N; M |-> M[x : A[Δ] := N]
Nat : Type;
String : Type;
\n[Γ] ⇒ B
-------------------- ----------------------
x\0[x : A][Γ] ⇒ A[Γ] \(1 + n)[x : A][Γ] ⇒ B
M[x : A][Γ] ⇒ B[Δ]
--------------------------------------
((x : A) => M)[Γ] ⇒ (x : A[Γ]) -> B[Δ]
M[Γ] ⇒ ((x : A) ⇒ B)[Δ] N[Γ] ⇒ A[Δ]
------------------------------------
(M N)[Γ] ⇒ B[x : A := N][Δ]
(x => x) 1
[x == 1] |- x
[x == 1] |- 1
f : (x : Nat) -> Nat;
f : (X = Nat; (x : X) -> X);
(f 1) : Nat
(f 1) : (X = Nat; X)
((x => x) : (x : Nat) -> Nat)
((
y = 2;
x => x
) : (x : Nat) -> Nat)
(incr : (x : Nat) -> Nat) = (
k = 1;
x => x + 1
);
add = n + 1 + 1 + 1 ... m
mul = n + n + n + n ... m
pow = n * n * n * n ... m
64 + 1
n + n
64 + 64
x\0[x : Nat\1][Γ] ⇒ Nat\1[Γ]
----------------------------------------------------
((x : Nat\1) => x\0)[Γ] ⇒ (x : Nat\1[Γ]) -> Nat\1[Γ]
x\0[x : A\1] ⇒ A\1
----------------------------------------
x\1[f : (y : A\2) -> A\3][x : A\1] ⇒ A\1
A\1 ≡ A\2[x : A\1]
f\0[f : (y : A\2) -> A\3][x : A\1] ⇒ ((y : A\2) -> A\3)[x : A\1]
----------------------------------------------------------------------
(f\0 x\1)[f : (y : A\2) -> A\3][x : A\1] ⇒ A\3[y : A\2 := x\0][x : A\1]
-----------------------------------------------------------------------
((x : A\1) => (f : (y : A\2) -> A\3) => f\0 x\1)[Γ] ⇒
(x\1[y][x : Nat\1] : Nat\1)
(y => x)[x : Nat\1] : (y : _) -> Nat\2
(x : Nat\1) => x\0
[x : A] |- x\0 ⇒ B[Δ]
y = (x\1[y][x : Nat\1 == _] : Nat\1);
Γ[x : A] |- M ⇒ B[Δ]
-----------------------------------
Γ |- (x : A) => M ⇒ (x : A) -> B[Δ]
(x : Nat\1) => (x\0[x : Nat\1])
(\0[x : Nat\1] : Nat\1)
Nat\2[x : Nat\2]
x
x => M
M N
(x => y => x) == (y => x => y)
(_ => _ => \1) == (_ => _ => \1)
(x => y => x)
(x => y => z => x)
(Nat => (x : Nat\1) => y => z => (x\2 : Nat\4))
----------
Γ |- M : A
---------------------
Γ, x : A\1 |- x : A\2
----------------------
x[x : A\1][Γ] : A\1[Γ]
Γ |- A : Type Γ, x : A |- B : Type
-----------------------------------
Γ |- (x : A) -> B : Type
------------------------------
[x : A] |- (y : A) -> A : Type
----------------------------
((y : A) -> A)[x : A] : Type
(x => x y)
\n[Γ] ⇒ B[Δ]
------------------- -------------------------
\0[x : A][Γ] ⇒ A[Γ] \(1 + n)[x : A][Γ] ⇒ B[Δ]
// term-level
\n[Γ] ⇒ B
------------------- ----------------------
\0[x : A][Γ] ⇒ A[Γ] \(1 + n)[x : A][Γ] ⇒ B
M[x : A][Γ] ⇒ B[x : A]
--------------------------------
((x : A) => M : (x : A) -> B)[Γ]
M[(x: A[Δ]) => _][Γ] ⇐ B[(x : A) -> _][Δ]
-----------------------------------------
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
M[Γ] ⇒ ((x : A) ⇒ B)[Δ] N[Γ] ⇒ A[Δ]
------------------------------------
(M N)[Γ] ⇒ B[x : A := N][Δ]
------------------------------
(Γ |- x => M) ⇐ (Δ |- (x : A) -> B)
-------------------------------
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
(x => M : (x : Nat) -> Nat)
((
y = 1;
x => M
) : (x : Nat) -> Nat)
(x => M : (
X = Nat;
(x : Nat) -> Nat
))
-----------------------------
\0[x : A][Γ] ⇒ A[↑][x : A][Γ]
\n[Γ] ⇒ B[Δ]
-----------------------------------
\(1 + n)[x : A][Γ] ⇒ B[↑][x : A][Δ]
M[(x : A) => _][Γ] : B[x : A][Δ]
------------------------------------- // dc-lambda
((x : A) => M)[Γ] : ((x : A) -> B)[Δ]
B[↑][x : A][Δ] == B[Δ]
Context (Γ) ::= _ | Γ[x : A] |;
x[x : A]
------------------- // i-head
\0[x : A][Γ] ⇒ A[Γ]
\n[Γ] ⇒ B[Δ]
------------------------- // i-tail
\(1 + n)[x : A][Γ] ⇒ B[Δ]
M[x : A][Γ] ⇒ B[x : A][Γ]
------------------------------------- // i-lambda
((x : A) => M)[Γ] ⇒ ((x : A) -> B)[Γ]
M[Γ] ⇒ ((x : A) -> B)[Δ] N[Γ] ⇐ A[Δ]
---------------------------------- // di-apply
(M N)[Γ] ⇒ B[x : A = N][Δ]
M ≡ M[↑][x : A]
------------------- // i-head
\0[x : A][Γ] ⇒ A[Γ]
n[Γ] ⇒ B[Δ]
------------------------- // i-head
\(1 + n)[x : A][Γ] ⇒ B[Δ]
M[x : A][Γ] ⇒ B[x : A][Γ]
------------------------------------- // i-lambda
((x : A) => M)[Γ] ⇒ ((x : A) -> B)[Γ]
M[x : A[Δ]][Γ] ⇐ B[x : A][Δ]
------------------------------------- // dc-lambda
(x => M)[Γ] ⇐ ((x : A) -> B)[Δ]
M[Γ] ⇒ ((x : A) -> B)[Δ] N[Γ] ⇐ A[Δ]
------------------------------------- // di-lambda
(M N)[Γ] ⇒ B[x : A = N][Δ]
x\0[x : Nat\0][Nat : Type] ⇒ Nat\0[Nat : Type]
-----------------------------------------------------------
((x : Nat\0) => x\0)[Nat : Type] : (x : Nat\0) -> Nat\0[↑]
Nat\0[Nat : Type] == _B[x : Nat\0][Nat : Type]
Nat\0 == _B[x : Nat\0]
Nat\0[↑][x : Nat\0] == _B[x : Nat\0]
Nat\0[↑] == _B
Nat\1[Nat\1 : Type] == _B[x : Nat\1][Nat\1 : Type]
Nat\1 == _B[x : Nat\1]
Nat\1[↑] == _B
f : (X = Nat; (x : Nat) -> X);
(x => x + 1 : (x : Nat) -> Nat)
((
one = 1;
x => x + one
) : (x : Nat) -> Nat)
(λx. λy. t) u ~ λy. ((λx. t) u)
(λy. t)[x := u] ~ λy.t[x := u]
λy. t[x := u] ~ λy.t[x := u]
(λx.t v) u ~ (λx.t) u v
(t v)[x := u] ~ t[x := u] v
(t v)[x := u] ~ t[x := u] v
(λ.t v) u ~ (λ.t) u v
(t v)[u] ~ t[u] v
Term ::= n | λM | M N | M[S];
Subst ::= N | ↓;
0[N] |-> N // head
(1 + n) |-> n // drop
(M N) |-> M[↓][N] // db
(λM)[↓] |-> M // skip
Term ::= x | x => M | M N | M[x := N] | M[apply N];
x[x := N] |-> N
(y => M)[x := N] |-> (y => M[x := N])
(M N) |-> M[apply N] // beta
(x => M)[apply N] |-> M[x := N] // skip
x[apply N]
(f v)[y := u]
f[apply v][y := u]
((x => t) v)[y := u]
(x => t)[apply v][y := u]
t[x := v][y := u]
Term ::= n | λM | M N | M[S];
Subst ::= N | ⇑S | ⇓S;
0[N] |-> N
(1 + n)[N] |-> n
0[⇑S] |-> 0
(1 + n)[⇑S] |-> n[S]
(λM)[S] |-> λM[⇑S]
(M N) |-> M[⇓N] // db
(λM)[S] |-> M // skip
((λt) v)[u]
(λt)[⇓v][u]
t[v][u]
(λ1)[u]
(t v)[u]
t[↓][v][u]
((λt) v)[u]
-
(λt)[↓][v][u]
t[v][u]
((λt) v)[u]
- t[v][u] // beta
- t[u][v] // propagation first
((x => t) v)[y := u]
- t[x := v][y := u] // beta
- t[y := u][x := v] // propagation first
λM[↓] |-> M // elim-lambda
M[N][↓] |-> M // elim-subst
λM[↓] |-> M // elim-lambda
λM[↓] |-> M // elim-lambda
λ(0[↑]) |-> M // skip-lambda
λ(0[↑]) |-> M // skip-binder
λM[↓] |-> M // elim-lambda
M N |-> M[↓][N] // weird-beta
λ0 |-> 0[↓]
(λ0) N |-> N
(λ0[↑])[N][↓] |-> N
(λM) N
(f 1) : (X = Nat; X)
Nat\1[Nat\1 : Type] == _B[x : Nat\1][Nat\1 : Type]
Nat\1 == _B[x : Nat\1]
Nat\1[↑][x : Nat\1] == _B[x : Nat\1]
Nat\1[↑] == _B
Nat\1[↑] == Nat\1[↑]
Nat\1[↑][↑][x : Nat\1] == _B[x : Nat\1]
Nat\1[↑][↑] == _B
Nat\1[↑] == _B[x : Nat\1]
_Δ := ↑
Nat\1 == _B[x : Nat\1]
Nat\1[↓] == _B[x : Nat\1][↓]
Nat\1[↓] == _B
Nat\1[] == _B
_B[x : Nat\1][_Δ]
⇒ Nat\1[↑]
------------------
⇒ (x : Nat\1) ->
Nat\1[↑] ==
(x : Nat\1) => (x\0 : Nat\1[↑])
⇒
--------------------
(x : Nat\1) => \0 ⇒ ((x : Nat\1) -> Nat\1)
_Δ := ↑
M ⇒ K[↑][↑]
-------------------------
x => M ⇒ ((A : Type) -> B)[↑][↑]
Nat\1[↑] == Nat\1[↑]
Nat\1 == _B[x : Nat\1]
Nat\1[↑][x : Nat\1] == _B[x : Nat\1]
Nat\1[↑] == _B
Nat\1[↑] == _B[x : Nat\1]
Nat\1 == _B[x : Nat\1][_Δ]
received : Nat\1[Δ]
expected : _B[x : Nat\1][Δ]
_B := Nat\1[↑]
Term (M, N) ::= 0 | λM | M N | M[S];
Subst (S) ::= N | ↑ | ↓;
0[N] |-> N
0[↑][N] |-> n
0[N][↓] |-> n
0[⇑S] |-> 0
0[⇓S] |-> 0
M[↑][⇑S] |-> M[S][↑]
M[↓][⇓S] |-> M[S][↑]
M N |-> M[⇓N] // Beta
(λM)[⇓S] |-> M[S] // Skip
0[1][↓]
n[↓] |-> (1 - n)
0[1][↓] |-> 1[↓] |-> 0
0[2][↓] |-> 2[↓] |-> 0
M[↓][S] |->
M[S][↓] |->
(λM)[↓] == λM[⇑↓]
n[↓]
(λ0[↓]) (λλ0)
(λ0[↓])[↓][λλ0]
0[↓][λλ0]
0[↓][λλ0] ? 0[λ0]
M[S][↓]
(λ0[↓]) (λλ0)
(λλ0)[↓]
(0)[↓][N]
M[↑][N] |-> M // drop
(1 + n)[N] |-> n // drop
(λM)[N] |-> λM[⇑N]
(λM)[⇑S] |-> λM[⇑⇑S]
((λt) v)[u]
- t[v][u] // beta
(λ0)[N] |-> λ0
(λ1)[N] |-> λN
(λ2)[N] |-> λ1
Term (M, N) ::= 0 | λM | M N | M[S];
Subst (S) ::= N | ↑ | →;
M N |-> M[→][N]l
(λM)[→] |-> M
M[N][→] |-> M
M N
(λM)[N] |->
2[N]
M[N][↓] |->
M[↓][N] |->
(λ0)[N] |-> λ0
(λ1)[N] |-> λN[↑]
(λ2)[N] |-> λ1
Term (M, N) ::= 0 | λM | M N | M[S];
Subst (S) ::= N | ↑ | →;
Context (Γ) ::= _ | Γ, x : A | Γ, x : A = N;
Term (M, N)
Type (A, B) ::=
| (M : A) | Type | \n | x = N; M | x = N; M
| (x : A) -> B | (x : A) => M | M N | x => M | M[Δ];
Subst (Δ, Φ) ::= | M | Δ[x : A = N] | _[↑]
Variable (n) ::= 0 | 1 + n
Γ |- M ⇒ A[n] === M[Γ] ⇒ A[n][Γ]
Γ |- M ⇐ A[Δ][n] === M[Γ] ⇐ A[Δ][n][Γ]
Γ |- M[Φ] ≡ N[Δ] === M[Φ][Γ] ≡ N[Δ][Γ]
Γ |- A : Prop
--------------
Γ |- M ≡ N : A
Γ |- M ⇒ A[↑n]
Γ |- M ⇒ A Γ |- A[•] ≡ B[Δ][n] Γ |- (M : A) ⇐ A[•][0]
------------------------------- ----------------------
Γ |- M ⇐ B[Δ][n] Γ |- (M : A) ⇒ A
----------------
Γ |- Type ⇒ Type
Γ, x : A == N :
------------------------- // forget
Γ, x : A == N |- Γ, x : A
--------------------- // i-head
Γ, x : A |- \0 ⇒ A[↑]
Γ |- \n ⇒ B
--------------------------- // i-tail
Γ, x : A |- \(1 + n) ⇒ B[↑]
Γ, x : A |- M ⇒ B[Δ | n]
--------------------------------------- // i-lambda
Γ |- (x : A) => M ⇒ (x : A) -> B[Δ | n]
Γ, x : A |- B ⇒ Type[• | 0]
------------------------------- // i-forall
Γ |- (x : A) -> B ⇒ Type[• | 0]
Γ, x : A |- M ⇒ B[Δ | n]
--------------------------------------- // i-lambda
Γ |- (x : A) => M ⇒ (x : A) -> B[Δ | n]
Γ, x : A[Δ] |- M ⇐ B[y : A][Δ | 1 + n]
---------------------------------------- // dc-lambda
Γ |- x => M ⇐ ((y : A) -> B)[Δ | n]
Γ |- M ⇒ ((x : A) -> B)[Δ | n] Γ |- N ⇐ A[Δ | n]
------------------------------------------------- // di-apply
Γ |- M N ⇒ B[x : A = N][Δ | n]
Γ |- N ⇒ A[Δ] Γ[x : A[Δ] = N] |- M ⇒ B[Φ]
------------------------------------------- // dr-let-infer
Γ |- x = N; M ⇒ B[Φ][x : A[Δ] == N]
--------------------------------- // i-head
Γ, x : A | n |- x\+|Γ, x : A| ⇒ A
Γ |- \n ⇒ B[Δ | n]
----------------------------------- // i-tail
Γ, x : A |- \-(1 + n) ⇒ B[Δ | 1 + n]
(A : Type) => (x : _B) => (x : B\0 : A\1)
(x : _B) => (A : Type) => (x : A\0)
-----------------------------
Γ | Δ |- _x ≡ N -| Δ, _x := N
-----------------------------
Γ | Δ |- M ≡ _x -| Δ, _x := M
Γ |- M ⇒ B Γ |- B ≡ A -| Δ
---------------------------
Γ |- M ⇐ A -| Δ
Γ, x | y : A |- M[open +n] ≡ N[open +n]
------------------------------------------
Γ |- ((x : A) => M) ≡ ((y : A) => N)[Φ]
Γ, x : A |- B ⇒ K
-------------------------------------
Γ |- (x : A) -> B : K
incr = x => x + 1;
n = incr 1;
x : Nat;
x = x;
x
x[x := x]
Γ, x : A |- B ⇒ K
-------------------------------------
Γ |- (x : A) -> B : K
--------------------
Γ |- M[Φ] ≡ N[Δ] : K
Γ |- M[0 :: Φ @ ↑] ≡ N[0 :: Δ @ ↑]
----------------------------------
Γ |- (x => M)[Φ] ≡ (x => N)[Δ]
2[Δ @ ↑] == 2[Δ @ ↑]
Γ |- 1[Δ] == 1[Δ]
------------------------------------------
Γ |- (x => 1)[1 :: Δ] == (x => 2)[Δ]
Γ |- 2[0 :: 1[↑] :: M[↑] :: Δ @ ↑] == 2[0 :: N[↑] :: Δ @ ↑]
----------------------------------------------
Γ |- (x => 1)[Φ] == (x => 2)[Δ]
(M[K]) N
(M[K]) N
(M N)[K]
(M[K]) 0
(M[K] 0)
(0 _K)
(M[K] 0)
L<(λx. M) N> |-> L<M[x := N]>
M[↓][0][K]
(x = K; f x) N
(λ0)[K] N
(λ0) N
N
(λ0 1)[K] N
(λ0 K[↑]) N
N K
((λ0 1) 0)[K]
((λ0 1) 0)[K]
((λ0 K) K)
(K K)
0[0[K]
(x => 1)[1][3]
(x => y => M) "A" "B"
(x, y) = ("A", "B");
M[x := "A"][y := "B"]
pair => (
(x, y) = pair;
x + y
);
pair => (x + y)[(x, y) = pair];
pair => (x + y)[x := (x, y) = pair; x][y := (x, y) = pair; y]
pair => (((x, y) = pair; x) + ((x, y) = pair; y))
(x : Nat) -> Nat == (x : String) -> Nat
(x => 1)[0][0]
(x => 1[0 :: 0])
(x => 1)[1] == (x => 2)[id]
(String |> Token[] |> Ctree |> Ltree |> Ttree) // syntax
(Ttree |> Ttree) // checking
(Ttree |> Utree -> Jtree -> String) // jsend
(Syntax |> Jsend) // syntax + jsend
Nat64 : Data;
i < n : Prop;
Socket : Resource;
Array : {
get : <A, n>(arr : Array n A, i : Nat64 & i < n) -> A;
make : <A>(length : Int64 & length >= 0, initial : A) -> Array length A;
} = _;
safe_div : (n : Int64, m : Int64 & m != 0) -> Int64;
unsafe_div : (n : Int64, m : Int64) -[Division_by_zero]> Int64;
(n : Nat64) => (arr : Array n Int64) =>
(n : Nat64, arr : Array n Int64)
Array 15 Int64
(λx. M) N ≡ M[N]
(λM) N ≡ M[N]
M[K] N ≡ (M N[↑])[K]
M[0 . ↑] N ≡ M
(λ0 0[↑])[↑] N
(λ(0 0[↑])[0 :: ↑ @ ↑]) N
(λ(0 0[↑][↑])) N
(0 0[↑][↑])[N]
(λ0 (0[↑]))[↑] N
(0 2)[N]
(N 1)
(λ0 1)[↑] N
(0 1)[N . id]
(N[↑] 0)[↑]
(λ0 1)[↓][N[↑]][↓]
(N[↑] 0)[↓]
(λ0 1)[↓][↓][N]
(0 1)[N[↑]][↓]
(N[↑] 0)[↓]
(0 1)[↓][N]
(λ0 1)[↑][↓][N]
(λ0 2)[↓][N]
(0 2)[N]
(N 2)
(λ0 1)[↓][N[↓]][↑]
(0 1)[N[↓]][↑]
(N[↓] 1)[↑]
(N 2)
(M[↑] N)[K] ≡ M N[K]
((λ0)[↑] N)
((λ0) N)
((λ0) N)
((λt) v)[u]
- t[v][u] // beta
- t[⇑u][v]
(M[↑] N)
((λ0 1)[↑] N)
((λ0 2) N)
(N 1)
(M N)[↑] ≡ M[↑] N[↑]
M[↑][↓] == M[↓]
M[↑][N] == M
M[↑][0] == M
M[↑][N] == M[↑]
M[↑] == M[↑][0][↑]
0[↑][0] |-> 1 |-> 0
1[↑][0] |-> 2[0] |-> 1
2[↑][0] |-> 3[0] |-> 2
n[↑] ≡ (1 + n)
(1 + n)[↓] ≡ n
M[↑] N ≡ (M N[↑])[K]
(λM)[↑]
(λ0 1)[↑]
(λ0 2)
(λ(0 1)[↑][0])
(1[↓] N[↑])[↓]
(1 N[↑])[↓]
(0[↑]) 0 ≡ (0 0[↓])[↑]
M[S] N ≡ (M N[-S])[S]
((λt) v)[u]
- t[v][u] // beta
- t[⇑u][v]
(1 0)[v][u]
(0 v)
u v
(u v)
(λ0 1)[K] N
(λ(0 1)[⇑K]) N
(0 1)[⇑K][N]
(0 K)[N]
N K
(λ0 1)[K] N
(0 1)[N[↑]][K]
(N[↑] 0)[K]
(N[↑][K] 0)
(N[K] 0)
(λM) N |-> M[K][N]
(x => M) N |-> M[x := N] // beta
M[x := K] N |-> (M N)[x := K] // extract
C<x>[x := N] |-> C<N>[x := N] // ls
M[x := N] |-> M x ∉ fv(M) // gc
(λM) N |-> M[N] // beta
0[N] ≡ N
M[↑][N] ≡ M
(M N)[K] ≡ M[K] N[K]
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
(λλM[↑]) K
(λM[↑])[K]
λM[K][↑]
(λλ(0 0[↑])) K
(λ(0 0[↑]))[K]
λ(M N[↑])[K]
(λ(M N[↑])) == λ(0[↓] N)[↑]
(λ(0 0[↑])) == _ (λ0[↑])
(λλ(0 (0[↑] )))
λ(0 ((λ0 0) (λ0[↑])))
(λ(0 0[↑]))[λ0[↑]]
λ(0[↑])
λ(M N) ≡ (λM) (λN)
(λM) (λN)
(0 0[↑])[K]
(0 0[↑])[↓][K]
λ(0[↓] K)[↑]
λ(0 K[↑])
(λ(0 1)[])[K]
(λ(0 0[↑]))[K]
M[K][0]
0 :: (_ 0)[S]
0 :: (S 0)[S]
(M N)[S] ≡ M[S] N[S]
(M N)[0 ↑] |-> (M[n ↑] N[n ↑])
(λM)[n ↑] |-> λM[(1 + n) ↑]
n[m ↑] n < m |-> n
n[m ↑] n >= m |-> 1 + n
((y => t)[x := u] v)
((y => t) v)[x := u]
t[y := v][x := u]
M[x := K] N ≡ (M N)[x := K] // extract
M[K] N ≡ (M N[↑])[K] // using de-bruijin
(x => y => M) N K
(y => M)[x := N] K
((y => M) K)[x := N]
M[y := K][x := N] // names are preserved in order
// so
((x => y => M) N K) ≡ (x = N; y = K; M)
------------------
(x : Nat) & String
(x : String) & Nat
Γ |- S <: A Γ, x : A |- S <: B
-------------------------------
Γ |- S <: (x : A) & B
(M[K] N) ≡ (M N[↑])[K]
0[N] ≡ N
M[↑][N] ≡ M
(M N)[K] ≡ M[K] N[K]
// theorems
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
M[↑] N ≡
----------------------
M[↑]
Term ::= n | λM | M N | M[N];
(0)[N][Γ] |-> N
(1 + n)[N][Γ] |-> n[Γ]
((λM)[Δ] N)[Γ] |-> M[N[Γ]][Δ][Γ]
(λM)[Γ] ≡ (λM[0][Γ])[_]
(λ0 1)[N]
λ0[0][N] 1[0][N]
λ0 N[↑]
M[0][Γ] ≡ N[0][Δ]
-------------------------------------
(λM)[Γ] ≡ (λN)[Δ]
(M[K] : A)
M N |-> M[apply N]
(λM)[Δ][apply N] |-> M[N][Δ]
P 1 := _B[N]
(P 1)[↑][N] == _B[N]
(P 1)[↑] == _B
(P 1)[N] == _B[↑]
b
| true => (x : P true)
| false => (x : P false)
b (_ : true == true) _ : b == b
---------------
M N ⇐ B[x := N]
ind b _ _ : b == b
b == b == _B b
b == b == (λx. _M) b
b == b == _M[x := b]
(b == b)[b := x][x := b] == _M[x := b]
(x == x) == _M
b == b == _B b
_B := λ_M
b == b == (λ_M) b
b == b == _M[b]
_B := λ_M
n == n == (λ_M) n
n == n == _M[n]
(n == n) == _M[n]
(2 == 2) == _M[2]
(2 == 2)[0][1][2]
3 == 2 == (λ_M) 2
3 == 2 == (λ_M) 2
(λλλλ(3 == 2)) 3 2 1 0
(3 == 2)[0][1][2][3]
(1 == 0)[2][3] == _M[2]
(4 == 0)[2] == _M[2] // how
(λλλλ(3 == 2)) 4 2 1 0
(3 == 2)[0][1][2][3]
(3 == 2)[0][1][1][4][2]
(1 == 0)[1][4][2]
(0 == 1)[4][2]
(4 == 0)[2]
(4 == 0) == _M
(3 == 2)[2][3]
(1 == 0)[2][3] == _M[2]
(3 == 2)[0][1][2] == _M[2]
(1 == 0) == _M
(λ(1 == 0)) n
(λλλ(2 == 2)) 2 1 0 == _M[2]
(2 == 2)[0][1][2] == _M[2]
(2 == 2)[0][1] == _M
(0 == 0) == _M
(λλ(2 == 2)[0]) 1 2 == _M[2]
_M := (b == b)[↑]
b (_ : true == true) _ : b == b
_P true ≡ true == true
_P true ≡ true == true
(P true)
[N]|- (P 1)[↑] == _B
M[apply N :: Δ]
M[apply N][Δ]
C<0[N][Γ]> |-> C<N>
C<(1 + n)[N][Γ]> |-> C<n[Γ]>
(λM)[Γ] |-> λM[Γ]
(λ(0 1))[M][Γ]
λ(0 1)[0][M][Γ]
L<λM> N |-> L<M[N; |L|]>
M N
--------------------
Γ, x : A |- 0 ⇒ A[↑]
M[N] |-> M{N}
(λλ0 1)[k] N
(λ0 1)[0 := N]
(λ0[0 := N] 1[1 := N])
(λ0 1[1 := N])
(λ0)[↑] ≡ λ0
M[x := K] N ≡ (M N)[x := K]
M[↑] N ≡
M[K] N ≡ (M N)[x := K]
L<M>
------------------------
Γ, x : A |- M[↑] == N[_]
M N ≡ M[split][N] // beta
(λM)[split] ≡
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
(x => M) N |-> M[x := N] // beta
M[x := K] N |-> (M N)[x := K] // extract
Term ::= n | λM | M N | M[N] | M[↑] | M[Γ];
Env (Γ, Δ) ::= • | N :: Γ | Γ[↑];
M[N][Γ] |-> M[N :: Γ]
M[↑][Γ] |-> M[↑ :: Γ]
0[N :: Γ] |-> N
(1 + n)[N :: Γ] |-> n[Γ][↑]
n[Γ] |-> (1 + n)[Γ]
(λM)[Γ] |-> λM[0 :: Γ[↑]]
----------------------
Γ, x : A |- x\0 : A[↑]
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
M N |-> M[apply][N]
(λM)[apply] |-> M
M[K][apply][N] ≡ M[apply][N[↑]][K]
M[↑][apply][N] ≡ M[apply][↑][N]
0[N :: S] |-> N
(1 + n)[N :: S] |-> n[S][↑]
M[N][Γ] |-> M[N[Γ] :: Γ]
(M[↑])[N :: S] |-> M[S][↑]
M[↑][N] |-> M
(1 2)[0 :: 1 :: 1 :: 1]
(M N)[↑]
(λM)[↑] ≡ λM[0 :: 1]
0[N :: S] |-> N
(1 + n)[N :: S] |-> N
(0 1)
(λ0 1)[↑] ≡ λ0 2
(λ(0 1))[1] ≡ λ(0 1)[0 :: 1]
(λ(0 1))[0]
0 N |-> 0[apply]
Term ::= 0 | M[↑] | M[N] | λM | M N;
Env (Γ, Δ) ::= • | N :: Γ | Γ[↑];
M[↑ @ Γ] |-> M[Γ]{↑}
0[N :: Γ] ≡ N
M[↑][N :: Γ] |-> M[Γ]
M[N][Γ] ≡ M[N :: Γ]
M[↑][N] ≡ M
(λM) N ≡ M[N]
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
M[N][Γ] ≡ M[N :: Γ]
(M[K] N)[Γ] |-> (M N[↑])[K :: Γ]
(λM)[Γ] |-> λM[0 :: Γ[↑]]
(M[↑] N)[Γ] |-> (M N[↓])[Γ[↑]]
0[N :: Γ] |-> N
0[]
()
M N |-> M[apply][N]
(λM)[apply] |-> M
M[N][Γ] |-> M[N :: Γ]
M[↑][Γ] |-> M[↑ :: Γ]
f(x) = f(x) f is injective
x = x
g(x) = g(x)
Term (M, N) ::= x | x => M | M N | M[x := N];
(x => M)L N |-> M[x := N]L // db
M[x := N] |-> M{x := N} // s
Term (M, N) ::= x | x => M | M N | M[x := N];
(x => M) N |-> M[x := N] // beta
M[x := N] |-> M{x := N} // s
M[x := K] N ≡ (M N)[x := K] x ∉ fv(N) // move
Term (M, N) ::= n | λM | M N | M[N] | M[↑];
(λM) N |-> M[N] // beta
M[N] |-> M{N} // subst
M[↑] |-> M{↑} // shift
M[K] N ≡ (M N[↑])[K] // move
Term (M, N) ::= n | λM | M N | M[Γ];
Env (Γ) ::= • | ↑ :: Γ | N :: Γ;
(λM) N |-> M[N] // beta
M[Γ] |-> M{Γ} // shift+subst
M[K] N ≡ (M N[↑])[K]
M[K][Γ] ≡ M[K :: Γ]
M[↑][Γ] ≡ M[↑ :: Γ]
Term (M, N) ::= n | λM | M N | M[Γ];
Env (Γ) ::= • | ↑ :: Γ | N :: Γ | Γ @ ↑;
(λM) N |-> M[N] // beta
M[Γ] |-> M{Γ} // comp-shift+subst
(λM)[Γ] ≡ λM[0 :: Γ @ ↑]
M[K] N ≡ (M N[↑])[K]
M[K][Γ] ≡ M[K[Γ] :: Γ]
M[↑][Γ] ≡ M[↑ :: Γ]
Term (M, N) ::= n | λM | M N | M[Γ];
Env (Γ) ::= • | ↑ :: Γ | N :: Γ | Γ @ ↑;
(λM) N |-> M[N] // beta
M[Γ] |-> M{Γ} // comp-shift+subst
(λM)[Γ] ≡ λM[0 :: Γ @ ↑]
M[K] N ≡ (M N[↑])[K]
M[K][Γ] ≡ M[K[Γ] :: Γ]
M[↑][N] ≡ M
Term (M, N) ::= n | λM | M N | M[N];
L<λM> N |-> L<M[N]>
C<0>[N] |-> C<N{↑}>[N] // ls
M[N] |-> M{\downarr} 0 ∉ fv(M) // gc
(λC)<N> |-> λC<N[↑]>
Term (M, N, K) ::= n | λM | M N | M[Γ];
Env (Γ) ::= • | ↑ :: Γ | K :: Γ | Γ @ ↑;
(λM) N |-> M[N] // beta
M[Γ] |-> M{Γ} // comp-shift+subst
(λM)[Γ] ≡ λM[0 :: Γ @ ↑]
M[K :: •] N ≡ (M N[↑])[K]
M[K :: •][Γ] ≡ M[K[Γ] :: Γ]
M[↑ :: •][Γ] ≡ M[↑ :: Γ]
(↑ :: K :: Γ) ≡ Γ
↑ @ Γ, 0 |- M ≡ N
-----------------
Γ |- λM ≡ λN
Term (M, N, K) ::= n | λM | M N | M[Γ];
Env (Γ) ::= • | ↑ :: Γ | K :: Γ | Γ @ ↑;
M[0 :: Γ @ ↑] ≡ N[0 :: Δ @ ↑]
-----------------------------
(λM)[Γ] ≡ (λN)[Δ]
_M[0][K] ≡ _N[1][K]
_M[0] ≡ _N[1]
_M[K :: 0] ≡ _N[K :: 1]
M[K :: 0] ≡ _N[K :: 1]
M[↑][K :: 0]
M[↑][K :: 0]
M[↑][K :: 0]
_M[K :: 0] ≡ _N[K :: 1]
_M[0][K] ≡ _N[1]
0[0 :: 2] ≡ 0[1 :: 2]
_M[0] ≡ _N[1]
-----------
M[Φ] ≡ N[Δ]
-------------
• |- M[↑] ≡ N
0[↑][]
0[↑]
x => x
λ0
x => y => x
λλ1
x => y => y
λλ0
M ≡ N
-------
λM ≡ λN
(x => M)(N) |-> M{x := N}
(x => x + x)(1) |-> (x + x){x := 1} |-> (1 + 1) |-> 2
Term ::= n | λM | M N;
(λM) N |-> M{N} // beta
Term ::= n | λM | M N | M[N];
(λM) N |-> M[N] // beta
M[N] |-> M{N} // subst
Term ::= n | λM | M N | M[N];
(λM) N |-> M[N] // beta
M[K] N |-> (M N{↑})[K] // move
M[N] |-> M{N} // subst
M[x := K] N |-> (M N)[x := K]
(x => M)[y := N] |-> x => M[y := N]
M[x := N][y := K] |-> M[y := K][x := N]
(M[K] N)
(M{K} N)
(M N{↑})[K]
(x = K; y => M) N
(x = K; y => M) N
x = K; (y => M) N // move
(x = K; y = N; M)
Term (M, N, K) ::= n | λM | M N | M[Γ];
Env (Γ, Δ) ::= • | K :: Γ;
0[K :: Γ] |-> K
(1 + n)[K :: Γ] |-> n[Γ]{↑}
(λM)[Γ] |-> λM[0 :: Γ{↑}]
M[K][Γ] |-> M[K[Γ] :: Γ]
Term (M, N, K) ::= n | λM | M N | M[K];
(λM) N |-> M[N]
M[K] |-> M{K}
M[x := K] N |-> (M N)[x := K]
_M[K] N
(_M N)[K] // _M = λ_M2
(λ_M2 N)[K] // eta
_M2[N][K]
(_M N)
(λ((λ0) K) 0) N
(λK 0) N
((λ0) K) N
(λ0[K] 0) N
(0[K] 0)[N] // beta
(λK 0) N // s
(M[x := K] N)[x := K] -(s)> M[x := K] N x ∉ N
(M[x := x] N)[x := K] -(s)> M[x := K] N x ∉ N
(M N[x := K])[x := K] -(s)> M N[x := K] x ∉ M
M[x := K] N ≡ (M[x := K] N)[x := K] x ∉ N x ∉ K
(f = x => M; f) N |->
(f = x => M; f N) |->
Term (M, N, K) ::= 0 | λM | M N | M[K] | M[↑];
(λM) N |-> M[N]
M[K] N |-> (M N[↑])[K]
(M[↑] N)[K] |-> M N
0[K[Δ] :: Γ] |-> K[\Del]
(1 + n)[K :: Γ] |-> n[Γ][↑]
n[↑ :: Γ] |-> (1 + n)[Γ]
(λM)[Γ]
0[↑][K :: N :: _]
0[↑][K :: N :: _]
0[↑][K][N]
0[↑ :: K :: N]
1[K :: N]
Term (M, N, K) ::= n | λM | M N | M[K];
(λM) N |-> M[N] // beta
M[K] N |-> (M N{↑})[N] // move
M[K] |-> M{K} // subst
Term (M, N, K) ::= n | λM | M N | M[K] | M[↑];
------------------------------
0 | S | N :: E |-> N :: C | E
λM :: S | E ≡ M :: λ_ :: S | 0 :: E
M N :: S | E ≡ M :: _ N :: S | E
M N :: S | E ≡ N :: M _ :: S | E
M N | | E |-> M | _ N :: S | E
M | _ N :: S | E |->
----------------
M N
(λM) N |-> M[N] // beta
M[K] N |-> (M N[↑])[N] // move
M[K] |-> M{K} // subst
(λM) N :: Γ |-> M{N} :: Γ // beta
(λM) N :: Γ |-> M{N} :: Γ // beta
-----------------
0 | Γ | |->
-----------------
0 | Γ | |->
------------------------
λM :: Γ |-> M :: λ_ :: Γ
M |-> λK
--------------
M N |-> λK
C<(λM) N> |-> M[N] // beta
(λ((λ0) K) 0) N
((λ0) K) N // beta
(λK 0) N // beta
(M[K] N) |-> M_K N // subst
(M[K] N) |-> (M N{↑})[K] // move
(M N{↑})[K] |-> M_K N // subst
Term (M, N, K) ::= n | λM | M N | M[K] | M[↑];
M[K] N ≡ (M N)[K] if ∅ ≡ fv(N)
M[↑] N ≡ (M N)[↑] if ∅ ≡ fv(N)
M[K] N ≡ (M N[↑])[K]
M[↑] N ≡ (M N[↑])[1 :: ↑]
(M[↑] 0) ≡ (M N[↑])[0]
M[↑] N ≡ (M N[])[↑]
Term (M, N, K) ::= n | λM | M N | M[K] | M[↑] | M[_];
0[K] |-> K
(1 + n)[K] |-> n[K][↑]
M[K] N |-> (M N[↑])[K]
M[↑] N |-> (M N[↑])[_]
M[_] N |-> (M N[↑])[_]
M[_][K] |-> M[K]
M[↑][K] |-> M
M[K] |-> M{K}
M[↑] |-> M{↑}
(M[↑] N)
(M[↑] N) |-> (M N[↑])[_]
(0[↑] N)[T][U] |-> (U N[T][U])
(0[↑] N)[_]
M[_][T]
M[T]
(0[↑] N[↑])[_K]
(0[↑] N)
(0[↑][↑] N[↑])[_K]
(0 N[↑])[_K]
M[↑] N |-> (M N[↑])[_K]
(M N[↑])[0 / _K][0 / U]
M[↑] N |->
M[K] N ≡ (M N[↑])[K]
(M[↑] N)[K] ≡ M N[K]
(M[↑] N) ≡ (M N[↑])[_U]
(M[↑] N)[K] ≡ M N[K]
(M[↑] N)[_U] ≡ M N[_U]
(M[↑] N)[K]
M[_A] ≡ M[K]
_A ≡ K
((x = K; M) N) |-> (x = K; M N) // preserves
(M (x = K; N)) |-> (x = K; M N) // shrunken
(x = (y = K; N); M) |-> (y = K; x = N; M)
Term (M, N, K) ::= n | λM | M N | M[Γ];
0[N :: Γ] |-> N
(1 + n)[N :: Γ] |-> n[Γ][↑]
(λM)[Γ] |-> λM[0 :: Γ]
(λM)[Δ] N |-> M[N :: Δ]
M N
M[x := N][y := K]
M[y := K][x := N]
M[x := z][y := K][z := N]
M[0 :: 0 :: Δ][N][K] |-> M[N :: Δ]
M[0 :: 0 :: Δ][N :: K] |-> M[0 :: 0 :: Δ @ N :: K]
M[0 :: 0 :: Δ @ N :: K]
(N :: Δ @ K :: Γ) ≡ (N[K] :: Δ @ Γ)
0[0 :: 0 :: Δ][N][K]
N[K]
1[0 :: 0 :: Δ][N][K]
K
0[0 :: 0 :: Δ][N :: K]
N
1[0 :: 0 :: Δ][N :: K]
K
M[0 :: Δ] |->
M[0 :: Δ]
M[N][Γ] |-> M[N[Γ] :: Γ]
(λM)[Γ] |-> λM[0 :: Γ]
(λM)[0 :: Δ] N |-> M[N :: Δ]
Term (M, N, K) ::= n | λM | M N | M[Γ];
Context (Γ) ::= _ | ↑n | N :: Γ;
0[N :: Γ] |-> N
(1 + n)[N :: Γ] |-> n[Γ][↑]
(λM)[Γ] |-> λM[0 :: Γ]
(λM)[Δ] N |-> M[N :: Δ] // db
(x => M) N |-> N[x := M]
N[x := M] |-> (x => M) N
(x => M) N ≡ N[x := M]
Term (M, N, K) ::= n | λM | M N;
Env (Δ, Φ) ::= K :: Δ | ↑ :: Δ;
(λ0 1)[↑] N |-> (0 2)[N] |-> N 1
(λ0 1)[↑] N |-> (0 1)[N :: ↑]
((λ0 1)[↑] N)[K] |-> (λ0 1) N[K] |-> (0 1)[N[K]] |-> N[K] 1
(λ0 1)[↑][↑] N |-> (0 3)[N] |-> N 2
(λ0 1)[↑][↑] N |-> (0 1)[N :: ↑↑]
(λ0 1)[K][↑] N |-> K[↑][N]
(λ0 1)[K][↑] N |-> (0 3)[N] |-> N 2
0[N :: ↑] 1[N :: ↑]
(λM)[↑] N |-> M[N][↑]
(λ0 1)[↑] N |-> (0 1)[N][↑]
(M[↑] N)[K] |-> M N[K]
M N |-> (M N)[↑]
(λM) N |-> M[N] // beta
M[N] |-> M{N} // subst
f x ((x => M) N)
Term (M, N, K) ::= n | λM | M N | M[Δ | s];
Env (Δ, Φ) ::= • | N :: Δ;
M[• | s] |-> M
0[N | s] |-> N[• | s]
(1 + n)[N :: Δ | s] |-> n[Δ | 1 + s]
(λM)[Δ | s] |-> λM[0 :: Δ | s]
(λM)[Δ | s] N |-> M[N :: Δ | s]
(M N)[Δ | s] |-> M[Δ | s] N[Δ | s]
M[↑][K :: Δ | s] |-> M[Δ | 1 + s]
Γ |- M[N :: Φ] ≡ K[Δ]
-----------------------
Γ |- ((λM) N)[Φ] ≡ K[Δ]
Γ |- M[0 :: Φ] ≡ N[0 :: Δ]
--------------------------
Γ |- (λM)[Φ] ≡ (λN)[Δ]
N[0 :: Δ][Γ]
N[Δ][0 :: Γ]
Γ, 0 |- M ≡ N[0 :: Δ]
---------------------
Γ |- λM ≡ (λN)[Δ]
Γ |- M[↑] ≡ M
-----------------
Γ |- (λM)[↑] ≡ λM
(M[↑] )[K]
(λ0 1)[↑] N |-> (0 1)[N :: ↑]
Term (M, N, K) ::= n | λM | M N | M[Δ | s];
y : A;
x : A;
x = y;
y = x;
M
y : A;
x : A;
x = y;
y = x;
M
x : A;
y : A;
x = y;
y = x;
[0 / 0 : A];
[0 / 0 : A];
[0 / 1 : A];
[0 / 1 : A];
M
0[0 / 1][0 / 1]
1[0 / 1][0 / 1]
M[1][1][0][0]
M[1][0]
M[x := y][y := x]
M[1 :: 1]
M[0][2][2][3]
0[1 :: 0]
2[1 :: 2 :: 2 :: 3]
0[1 :: 1 :: 0 :: 0] |-> 1[1 :: 1 :: 0 :: 0]
1[1 :: 0] |-> 0[1 :: 0] |-> 1[1 :: 0]
1[1 :: 0] |-> 0[1 :: 0] |-> 1[1 :: 0]
1[Γ] |->
(λM)[Γ] |-> λM[0 :: Γ]
n[Γ] |-> n{Γ}[Γ]
0[K :: Γ] |-> K[|K| :: Γ]
(1 + n)[]
0[0 :: Γ] |-> 0[{0} :: Γ]
(λM)[Γ] |-> λM[0 :: Γ]
((λM)[Δ] N) |-> M[N[↑] :: Δ]
Term (M, N, K) ::= x | x => M | M N | M[x := N];
x[Γ] |-> x{Γ}[Γ]
Γ, x := z, y := z |- M ≡ N
--------------------------
Γ |- (x => M) ≡ (y => N)
Γ, x := z, y := z |- _A ≡ y
---------------------------
Γ |- (x => _A) ≡ (y => y)
Γ, x := z, y := z |- _A ≡ y
---------------------------
Γ |- (x => _A) ≡ (x => y)
Γ, x := z, y := z |- _A ≡ y
---------------------------
Γ |- (x => _A) ≡ (x => y)
Γ, x := z, y := z |- _A ≡ z[z := x]
Γ |- y => x == x => y
-----------------------------------
Γ |- (x => y => x) == (y => x => y)
Γ, y := a, x := a |-
---------------------
Γ |- y => x == x => y
x : A;
y : A;
x = y;
y = x;
M
x : A;
y : A;
x = y;
y = x;
M
M[0 / 1][1 / 0]
M[0 / 1][1 / 0]
M[1 :: 0]
(x : Nat) => (x == x + 1) => _
M[0 == N][1 == K]
M[0 == N][0 == K]
M[0 == N][2 == K]
M[0 == N | 1 == _ | 2 == K]
M[0 == N | 1 == K]
M[0 == 1][1 == 0][0][0]
M[0 == 1][1 == 0][0][0]
M[0 == 1][2 == 0]
M[0 == 1][1 == 0]
(λM)[0 == 1]
λM[↑ | 0 == 1]
M[0 == 1 | 2 == 0]
0[0 == 1][1 == 0][0][0]
1[0 == 1][1 == 0][0][0]
M[0][0][_][_]
M[0 :: 1 :: _][_]
x : Nat;
x = x + 1;
[_ : Nat]
[]
(x : Nat) => (x == x + 1) => _;
Γ |- (y => x) == (x => y)
-----------------------------------
Γ |- (x => y => x) == (y => x => y)
Term (M, N, K) ::= n | λM | M N;
x : A;
y : A;
y = x;
x = y;
M
n[Γ] |-> K[Δ]
-----------------------------------
(1 + n)[m == K][Γ] |-> K[m == K][Δ]
(λM)
(λM)[0 := 1][1 := 0]
M[0 / A][0 / B][0 / C]
M[0 / A :: 0 / B][0 / C]
(1 0)[0 / N][0 / K]
(1 0)[0 / N][0 / K]
x : A;
y : A;
y = x;
x = y;
M
(x : A) => (y : A) => (y == x) => (x == y) => _;
x : A;
y : A;
x = y;
y = x;
M
Term (M, N, K) ::= n | λM | M N | M[N; ...] | M[↑];
Env (Γ, Δ, Φ) ::= • | N :: Γ | Γ[↑ n] | Δ @ Γ[↑ n];
M[K][Γ] |-> M[K; Γ @ ↑]
M[Δ][Γ | n]
M[Δ][↑][Γ | n]
0[N :: _][↑][Γ | 0]
0[N :: _][Γ | 1]
N[↑][Γ | 0]
0[↑][Γ | 1]
0[↑][A :: B :: Γ]
1[A :: B :: Γ]
B[A :: B :: Γ]
0[↑][0 | A :: B :: Γ]
0[1 | A :: B :: Γ]
B[0 | A :: B :: Γ]
0[K][↑][0 | A :: B :: Γ]
0[K][1 | A :: B :: Γ]
0[N][K][A :: B :: Γ]
0[N][K][↑][A :: B :: Γ]
0[N][K][1 | A :: B :: Γ]
0[N][K][↑][A :: B :: Γ]
0[N[↑] :: K[↑] :: A :: B :: Γ]
N[N :: K[↑] :: A :: B :: Γ]
0[N][K][↑][A :: B :: Γ]
0[N][K][↑][A :: B :: Γ]
M[N][K][↑][Γ]
M[N][K][1 | Γ]
M[N][K][1 | K :: Γ]
M[N][K][Γ]
M[N][K :: Γ{↑}]
M[N :: K[↑] :: Γ{↑}]
N[K][↑]
0[N[↑] :: K[↑][↑] :: •][↑]
K[↑][N][K][↑]
1[N[↑] :: K[↑][↑] :: •][↑]
M[1][0]
M[N][K][0 | K :: Γ{↑}]
0[N][K][↑][Γ]
N[K][↑][Γ]
0[N][K][1 | Γ]
0[N][0 | K :: Γ{↑}]
0[0 | K[↑] :: A :: B :: Γ]
1[0 | K[↑] :: A :: B :: Γ]
0[K[↑]][↑][0 | A :: B :: Γ]
0[0 | (1 | K :: A :: B :: Γ)]
K[1 | K :: A :: B :: Γ]
M[N :: •][↑][Γ | 0]
M[N :: •][Γ | 1]
M[N :: Γ | 1]
M[Δ ][Γ] |-> M[Δ @ 0 | Γ]
n[Δ | d][Γ | g] |-> (n + d)[Δ][Γ | g]
N :: Δ[↑ n] @ n | Γ |-> Δ | n @ 1 + n | Γ
Δ | n @ Γ |->
• @ n | Γ |-> Γ @ ↑n
N :: Δ @ n | Γ |-> Δ @ 1 + n | Γ
M[↑][Γ | n] |-> M[Γ | 1 + n]
(eq : Nat == Bool) => not (eq _ 1)
(eq : Nat == Bool) => not 1
[eq] |- not 1
(eq : Nat == Bool) => not 1
(eq : Nat == Bool) => (not (1 : Bool))
(eq : Nat == Bool) => (not (1 : Bool))
M[0 := N; 1 := K]
0[A][0 := N; 1 := K]
0[0 := A; 1 := N[↑]; 2 := K[↑]]
(λM)[n := N] |-> λM[1 + n := N[↑]]
(λM[1 := N[↑]])
M[1 := N][Γ] |-> M[Γ + 1 := N]
m[Γ | n] |-> (m + n)[Γ]
m[↑][Γ | n] |-> m[↑][Γ | 1 + n]
1[1 := N][_ :: 1 :: Γ]
n[1 :: 0]
(x : Nat) => (x == )
(λM)[]
Term (M, N, K) ::= n | λM | M N | M[N; ...] | M[↑];
Env (Γ, Δ, Φ) ::= • | N :: Γ | Γ[↑ n] | Δ @ Γ[↑ n];
1[1 :: 0 :: Δ]
(x => M) N |-> M{x := N}
1[- 0 | 1 :: - 1 | 0 :: Δ]
1[- 0 | 1 :: - 1 | 0 :: Δ] |-> 0[- 0 | 1 :: - 1 | 0 :: Δ]
1[- 0 | 1 :: 0 | 0 :: Δ]
1[- 0 | 1 :: 0 | 0 :: Δ]
(M[↑] : A)[K]
(M[↑] N)
(M[↑] : A) |-> (M[↑] : A)
M[↑][n | A :: B :: Δ]
M[1 + n | A :: B :: Δ]
(M[↑] N)[0 | A :: B :: Δ]
(M N[↓])[1 | A :: B :: Δ]
(M[↑] N)[0 | A :: B :: Δ]
(M[↑] N)[K] |-> M N[K]
(M[↑] N)[0 | A :: B :: Δ]
(M[↑] N)[0 | A :: B :: Δ]
(M N[↓])[1 | A :: B :: Δ]
(M[↑] N)[1 | A :: B :: Δ]
Env ::= (n, N) :: (m, M) :: Δ
(M[↑] N)[0 | A :: B :: Δ] ≡ ( N)[0 | A :: B :: Δ]
((λM)[↑] N)[0 | Γ]
((λM)[↑][0 | Γ] N[0 | Γ])
((λM)[1 | Γ] N[0 | Γ])
(λM[0 :: Γ{↑ 1}]) N[0 | Γ]
((λM)[↑] N)[n | Γ] |-> M[N :: _ :: ]
(λM)[↑][n | Γ] |-> M[N :: _ :: ]
((λM)[↑] N)[n | Γ] |-> M[N :: _ :: ]
M[↑][Γ] |-> M[A :: B :: Δ]
M[K][↑][Γ] |-> M[K[A][↑] :: B :: Δ]
M[↑][Γ] |-> M[A | B :: Δ]
M[↑][A :: B :: Γ] |-> M[A | B :: Δ]
0[↑][A :: B :: Γ] |-> 0[A | B :: Γ]
0[A | B :: Δ] |-> B[A :: B :: Δ]
M[K][A | B :: Γ] |-> M[K :: B :: Γ]
M[K][A | B :: Γ] |-> M[A | B :: Γ]
[↑][Γ] |-> M[A | Γ]
M[K][↑][A :: B :: Γ] |-> M[K :: B :: Γ]
M[K][↑][A :: B :: Γ] |-> M[K :: B :: Γ]
M[↑][A :: Γ] |-> M[A | Γ]
M[K][A | Γ] |-> M[K :: Γ]
M[K][1 | Γ] |->
M[K][1 | Γ] |-> M[K :: Γ{↑}]
M[K][↑][A :: B :: C :: Γ] |-> M[K :: ↑ :: A :: B :: C :: Γ]
M[K][|Γ] |-> M[| K :: Γ]
M[K][A | B :: Γ] |-> M[A | Γ]
[A :: B :: C :: Γ]
[A; B :: C :: Γ]
M[↑][| A :: Γ] |-> M[A | Γ]
M[↑][| A :: Γ] |-> M[A | Γ]
M[K][n | A :: B :: Γ] |-> M[1 + n | A :: B :: Γ]
M[K][n | A :: B :: Γ] |-> M[1 + n | A :: B :: Γ]
x : A;
y : A;
x = y;
y = x;
Block ::= M; B | •
Env ::= M :: Γ | B :: Γ
M; N :: Γ
M[↑][N :: Γ] |-> M[Γ]
M[↑][A; Γ] |-> M[A | Γ]
M[↑][A :: Γ] |-> M[A | Γ]
M[K][A | Γ] |->
M[N][Γ] |-> M[N :: Γ]
0[N :: Γ] |-> N[Γ]
0[(N; B) :: Γ] |-> N[Γ]
0[Δ; N :: Γ] |-> N[Γ]
(1 + n)[Δ | N; B :: Γ] |-> N[Δ :: N | B :: Γ]
0[(0 1)[K] :: B :: Γ]
0[(0 1)[K] :: B :: Γ]
0[A :: B :: Γ]
M[K][N | B; Γ] |-> M[K :: N | B; Γ]
[0]
M[K][B[A]; Γ] |->
M[K][A | B; Γ] |->
M[K][A | B; Γ] |-> M[K :: B; Γ]
M[↑][|(N; B); Γ] |-> M[N :: •; B; Γ]
M[K][Δ | Γ] |-> M[Δ; K :: B; Γ]
M[↑][Δ; K :: B; Γ]
M[K][A :: • | B; Γ] |-> M[K :: B; Γ]
M[K][A | B; Γ] |-> M[K[0 := A] :: B; Γ]
0[A :: B :: Γ]
A[A :: B :: Γ]
[0 := 1][1 := 0][0, 0 :: 0, 0]
x =>
(x == N) =>
(x == M) =>
U = (A : Data, (A = A, A -> ()) -> ());
V = (A = U, A -> ());
Data (1 + _r) : Data (0 + _r)
Data (1 + 0 + _r) : Data (0 + _l)
_l := 1 + _r
U : Data 1 = (A : Data 0, (A = A, A -> ()) -> ());
V = (A = U, A -> ());
U : Data = (A : Data, (A = A, A -> ()) -> ());
(A = U, A -> ()) <: U
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A : Data 0, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: (A : Data (0 + _l), (A = A, A -> ()) -> ())
(A = _r⇑U, A -> ()) <: (A : Data (0 + _l), (A = A, A -> ()) -> ())
(A = _r⇑U, A -> ()) <: (A = _r⇑U, (A = A, A -> ()) -> ())
_l := 1 + _r
(A = _r⇑U, A -> ()) <: (A = _r⇑U, (A = A, A -> ()) -> ())
(A = _r⇑U, A -> ()) <: (A : Data (0 + _r), (A = A, A -> ()) -> ())
n⇑M : Data l |-> Data (l + n)
(A = _r⇑U, A -> ()) <: (A = _r⇑U, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: (A : Data (0 + _l), (A = A, A -> ()) -> ())
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A : Data (0 + _l), (A = A, A -> ()) -> ())
(A = _r⇑U, A -> ()) <: _e⇑U
(A = U, A -> ()) <: (A : Data (0 + _l), (A = A, A -> ()) -> ())
_l := 1 + _r
(A = _r⇑U, A -> ()) <: (A = _r⇑U, (A = A, A -> ()) -> ())
(A = _r⇑U, A -> ()) (A : Data (0 + _r), (A = A, A -> ()) -> ())
(A = U, A -> ()) -> U
(A : Data (0 + _l), (A = A, A -> ()) -> ()) <:=
(A = U, A -> ()) <: (A = U, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A = U, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: (A = U, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: U
V
----------------------------
(A : Data 1, x : A) : Data 1
(A : Data 0, x : A)
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A : Data 0, (A = A, A -> ()) -> ())
<r>(A = U<r>, A -> ()) <: U<e>
(A = U<_r>, A -> ()) <: (A : Data e, (A = A, A -> ()) -> ())
(A = U<_r>, A -> ()) <: (A : Data e, (A = A, A -> ()) -> ())
(A = U<e>, A -> ()) <: (A = U<e>, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: U
(A = U, A -> ()) <: (A : Data : Univ, (A = A, A -> ()) -> ())
(A = U, A -> ()) <: (A : Data, (A = A, A -> ()) -> ())
A = U
(A = _r⇑U, A -> ()) <: (A : Data (0 + _e), (A = A, A -> ()) -> ())
x : Nat;
eq : x == 1;
x = 1;
eq = refl;
M[0 :: 0]
M[↑][A :: B :: Γ]
M[↑][A | B :: Γ]
M[K :: A :: B :: Γ]
0[K :: A :: B :: Γ]
K[K :: A :: B :: Γ]
M[K][A | B :: Γ]
M[A | K :: B :: Γ]
0[↑]
(x => M)
(x => x + x)
(fn x => x + x)
(x => y => x + y)
[] | (λ.λ. \2 + \1) 15 13
15 :: [] | (λ. \2 + \1) 13
13 :: 15 :: [] | \2 + \1
13 :: 15 :: [] | 15 + 13
13 :: 15 :: [] | 28
[] | 28
2 | [15; 13; M] | \2 + \1
[15; 13; M]
[15; [N; 13]; M]
[15; [N; 13]; M]
read (sp - i)
read (2 - 1)
print : (msg : String) -[IO]> ();
map : <A, B>(l : List A, f : (x : A) -> B) -[Alloc (length l)]> List B;
((x : Int) => (1 : Nat)) <: ((x : Nat) => (1 : Int))
((x :))
-------------------
Γ |- \0[Φ] == \0[Δ]
-------------------
(x => M) ≡ (y => N)
(
Nat : Data;
Nat = <A>(zero : A, succ : (pred : Nat) -> A) -> A;
Nat
) = (
Nat : Data;
Nat = <A>(zero : A, succ : (pred : Nat) -> A) -> A;
<A>(zero : A, succ : (pred : Nat) -> A) -> A
)
(A : +Type) -> (P : (z : A) -> Type) -> (x : P x) -> P y
(x => x x) (x => x x)
Type : Type
Data : Type
Prop : Type
(M[K] N) |-> (M N[↑])[K]
(M[↑] N)[K] |-> M N[K]
∀
((f x) y) ≡ (f z)
Id = <A>(x : A) -> A;
f : (id : Id) -> Id = _;
x = f; // Id -> Id, no binder
(x => M N) K
((x : A : Type) => (M : B : Type) (N : C : Type)) (K : D : Type)
(1 : String : Type 0)
(Type 0)
(A : Type 0) =>
(String : Type 0)
A = @self(x). T
A : Type;
A = (x : A) & T;
((x : Id A) : A) = _;
map : ;
map = (l, f) => l | [] => [] | el :: tl => f(el) :: map(tl, f);
Id : [l] -> Type (1 + l) =
[l] => (A : Type l) -> (x : A) -> x;
id = (A : Prop) => (x : A) => x;
Type : Type
/M\
\M/
/M/
\M\
^
#macros
%macros
@
x%/* 1 */
33 !
34 "
35 #
36 $
37 %
38 &
39 '
40 (
41 )
42 *
43 +
44 ,
45 -
46 .
47 /
58 :
59 ;
60 <
61 =
62 >
63 ?
64 @
91 [
92
93 ]
94 ^
95 _
96 `
123 {
124 |
125 }
126 ~
32
46 .
33 ! 63 ?
64 @ 35 # 36 $
40 ( 60 < 91 [ 123 { 41 ) 62 > 93 ] 125 }
34 " 39 ' 124 |
42 * 43 + 45 - 47 /
37 % 94 ^
58 : 59 ; 61 =
38 & 44 ,
92 \
95 _ 96 `
126 ~
#(M : A)
M#[x := N]
M#[l]
#Type
x#1
(M : A)
M # match # N
#print
f # a
f # a
(f #) a
x#1
(a #1)
f a # 1
f a # 1
(f a)#1
x (#1)
f # debug
(f #) debug
f (# debug)
#print "Hello"
concat #"Hello" "World"
#\"Hello"
∀A. (x : A) -> A
#forall A. ((x : A) -> A)
#"Hello" = 1;
f #A
M = [%graphql {
users(id: 0) {
name
email
}
}];
M = [%graphql { users (id : 0) { name email } }];
f = [%c {
x: for (i = 0; i <= 10; i++) {
print(i);
};
if (true) {
print("a");
} else {
print("b");
};
goto x;
}];
#debug "Hello World"
(A : Type) => (x : A) => _
ind : <P : (b : Bool) -> Type>(b : Bool, then : P true, else : P false) -> P b;
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : (u : Unit) -> Type) -> (x : P unit) -> P u;
unit = P => x => x;
Bool : Type;
true : Bool;
false : Bool
Bool = (b : Bool) & (P : (b : Bool) -> Type) ->
(x : P true) -> (y : P false) -> P b;
true = P => x => y => x;
false = P => x => y => y;
ind (b : Bool)
: (P : (b : Bool) -> Type) -> (x : P true) -> (y : P false) -> P b
= b
Unit : Type;
unit : Unit;
Unit = (u : Unit) & (P : (u : Unit) -> Type) -> (x : P unit) -> P u;
unit = P => x => x;
Unit : Type = <A : Type>(x : A) -> A;
unit : Unit = x => x;
(x : A) & B
(x : Int) -> Int
(x : String) -> String
unit : ((x : Int) -> Int) & ((x : String) -> String) = x => x
f = (x : ((x : Int) -> Int) & ((x : String) -> String)) => _;
Id = <A>(x : A) -> A;
id : Id = x => x;
x : String = id "a";
id = (A : Data) => (x : A) => x;
x = id String;
Id = (A : Data) => A;
x : Id String = "Hello";
refl : <A>(x : A) -> x == x = _;
add = (a, b) => a + b;
_ : add (1, 2) == 3 = refl _;
Array : {
create : <A>(length : Int & length >= 0, initial : A) -> Array<A>;
} = _;
_ = (length : Int & (length >= 0) : Prop);
f = (length : Int) =>
length >= 0
| true => create
| false => _
(u : (A : Type#1) -> A#3) =>
(u : (A : Type#1) -> A#4)
[Type; String; u] + 0; [Type; String; u] + 0 |-
(A : Type#1) -> A#4 ≡ ((A : Type#1) -> A#3)#2
+ 0; [Type; String; u] + 0 |-
(A : Type#1) -> A#4 ≡ ((A : Type#1) -> A#3)#2
[Type; String; u];
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> A#4 ≡ ((A : Type#1) -> A#3)#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
A#4 ≡ A#3 // works
(A : Type : Meta)
((M : A : Data) : (A : Meta))
(1 : Meta)
((x : _a) => x + 1)
((x : int) => x + 1)
_A : Type <: Int
_A ≡ Int
_A := [Int]
_A ≡ String
_A := [Int; String]
_A := Int & String
P (not b) ≡ _F b
P (not b) ≡ (x => _M) b
P (not b) ≡ _M[x := b]
(P (not b))[b := x] ≡ _M[x := b][b := x]
(P (not b))[b := x] ≡ _M
_M := P (not x)
_F := x => _M
P (not b) ≡ (x => P (not x)) b
P (not b) ≡ P (not b)
STLC + Option + Int + String + List
(id : 'A. 'A -> 'A : Type 2)
(f : _B -> _) => f id
('K <: 'A. 'A -> 'A). (f : 'K -> _) => f id
'B. (f : ('B -> 'B) -> _) => f id
_A : Type 0
_A :=
|--|
λ. λ.-1
|-----|
λ. λ.-2
|--|
λ. λ.+1
|-----|
λ. λ.+0
Int#+1 -> ((A : Type) -> A#-1) -> ()
λA. λ(x : A#1 -> A#1). (x : A#2 -> A#2)
λA. λ(x : (∀A. A#2)). (x : (∀A. A#3))
5
id = (M : _A#6 -> _A#6);
id = (M : 'A. 'A -> 'A);
id = (M : 'A#-1 -> 'A#-1);
Mono (τ) := σ -> τ | A#+l
Poly (σ) := τ | ∀. σ
Term =
| T_arrow
| T_var of { level : int }
Type = { mutable desc : Desc; mutable level : int }
Desc =
| T_arrow
| T_var
| T_link of { to_ : Type }
Type = { mutable desc : Desc; }
Desc =
| T_arrow of { param : Type; return : Type; }
| T_link of { to_ : Type }
| T_free_var of { mutable binder : int }
| T_bound_var of { mutable binder : int }
∀. A#-1 -> B#-1 -> B#-1
∀. A#g -> B#g -> B#g
∀. (∀. A#-1 -> B#-2) -> B#-1
∀. (∀. A#0#-1 -> B#1#-2) -> B#1#-1
(∀. A#0#-1 -> _B#1) -> _B#1
(x => M) ⇐ ((x : Int) -> Int)
((x : Int) => (M : Int)) ⇒ (x : Int) -> Int
_A := _A -> _A
gen (_A -> _A)
gen 4 (_A#+5 -> _A#+5)
gen (_A#G -> _A#G)
∀. (∀. A#-2 -> B#-1) -> A#-
T =
| (x : Int, tag == true, y : Int)
| (x : Int, tag == false);
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> A#4 ≡ ((A : Type#1) -> A#3)#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
A#4 ≡ A#3
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> x = A#4; x#5 ≡ (A : Type#1) -> (x = A#3; x#4)#2
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> (x = A#4 Type#1; x#5) ≡ ((A : Type#1) -> (x = A#3 Type#1; x#4))#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> x = A#4; x#5 ≡ (A : Type#1) -> x = A#3; x#4
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
x = A#4 Type#1; x#5 ≡ x = A#3 Type#1; x#4
[Type; String; u; A; x == A#4] + 0 | [Type; String; A + 1; x == A#3] + 1 |-
x#5 ≡ x#4
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
A#4 ≡ A#3
[Type; String; u] + 0 | [Type; String] + 1 |-
A#4 ≡ A#4
[Type; String; u] + 0 | [Type; String; u] + 0 |-
x = Type#1; x#4 ≡ (x = Type#1; x#3)#2
[Type; String; u] + 0 | [Type; String] + 1 |-
x = Type#1; x#4 ≡ x = Type#1; x#3
[Type; String; u; x == Type#1] + 0 | [Type; String; x == Type#1] + 1 |-
x#4 ≡ x#3
(A : Type) => (A : Type)
1 : (A : Type) => (x : A) => id A x
2 : (A : Type) => (x : A) =>
(((id : _A) (A : _B) : _C) (x : _D) : _E)
3 : (A : Type) => (x : A) =>
(((id : (A : Type) -> (x : A) -> A) (A : Type) : (x : A) -> A) (x : A) : A)
(abc) => abd
f(f(f(f(f(f(M))))))
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> (x = A#4 Type#1; x#5) ≡ ((A : Type#1) -> (x = A#3 Type#1; x#4))#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> (x = A#4 Type#1; x#5) ≡ (A : Type#1) -> (x = A#3 Type#1; x#4)
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
x = A#4 Type#1; x#5 ≡ x = A#3 Type#1; x#4
[Type; String; u; A; x = A#4 Type#1] + 0 | [Type; String; A + 1; x = A#3 Type#1] + 1 |-
x#5 ≡ x#4
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
A#4 Type#1 ≡ A#3 Type#1
[Type; String; u; A] + 0 | [Type; String; A + 1] + 1 |-
A#4 Type#1 ≡ A#3 Type#1
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> A#4 ≡ ((A : Type#1) -> A#3)#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String; u; A#4] + 0 | [Type; String; A#4] + 1 |-
A#4 ≡ A#3
[Type; String; u] + 0 | [Type; String] + 1 |-
A#4 ≡ A#4
[Type; String; u] + 0 | [Type; String; u] + 0 |-
(A : Type#1) -> (B : Type#1) -> A#4 ≡ ((A : Type#1) -> (B : Type#1) -> (A#3)#3)#2
[Type; String; u] + 0 | [Type; String] + 1 |-
(A : Type#1) -> (B : Type#1) -> A#4 ≡ (A : Type#1) -> (B : Type#1) -> (A#3)#3
[Type; String; u; A#4] + 0 | [Type; String; A#4] + 1 |-
(B : Type#1) -> A#4 ≡ (B : Type#1) -> (A#3)#3
[Type; String; u; A#4; B] + 0 | [Type; String; A#4; B] + 1 |-
A#4 ≡ (A#3)#3
[Type; String; u; A#4; B] + 0 | [Type; String; A#4] + 1 |-
A#4 ≡ A#3
3 | [Type; String; u] | [Type; String; u] |-
(A : Type#1) -> (B : Type#1) -> A#4 ≡ ((A : Type#1) -> (B : Type#1) -> (A#3)#3)#2
3 | [Type; String; u] | [Type; String; u] |-
(A : Type#1) -> (B : Type#1) -> A#4 ≡ ((A : Type#1) -> (B : Type#1) -> (A#3)#3)#2
3 | [Type; String; u] | [Type; String] |-
(A : Type#1) -> (B : Type#1) -> A#4 ≡ (A : Type#1) -> (B : Type#1) -> (A#3)#3
4 | [Type; String; u; A#4] | [Type; String; A#4] |-
(B : Type#1) -> A#4 ≡ (B : Type#1) -> (A#3)#3
4 | [Type; String; u; A#4; B] | [Type; String; A#4; B] |-
A#4 ≡ (A#3)#3
4 | [Type; String; u; A#4; B] | [Type; String; A#4] |-
A#4 ≡ A#4
[Type; String; u]#3 | [Type; String; u]#3 |-
(A : Type#1) -> (x = _; A#4) ≡ ((A : Type#1) -> A#3)#2
[Type; String; u]#3 | [Type; String]#3 |-
(A : Type#1) -> (x = _; A#4) ≡ (A : Type#1) -> A#3
[Type; String; u; A#4]#4 | [Type; String; A#4]#4 |-
(x = _; A#4) ≡ A#3
[Type; String; u; A#4; x]#5 | [Type; String; A#4]#4 |-
(A#4) ≡ A#3
[Type; String; u]#3 | [Type; String; u]#3 |-
x = _; (A : Type#1) -> A#5 ≡ ((A : Type#1) -> A#3)#2
[Type; String; u]#3 | [Type; String]#3 |-
x = _; (A : Type#1) -> A#5 ≡ (A : Type#1) -> A#3
[Type; String; u; x]#4 | [Type; String]#3 |-
(A : Type#1) -> A#5 ≡ (A : Type#1) -> A#3
[Type; String; u; x]#5 | [Type; String]#3 |-
(A : Type#1) -> A#5 ≡ (A : Type#1) -> A#3
[Type; String]#2 | [Type; String]#2 |-
x = _; (A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String; x = _; ]#3 | [Type; String]#2 |-
(A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String; x = _; A] | [Type; String; A] |-
A#4 ≡ A#3
[Type; String]#2 | [Type; String]#2 |-
x = _; (A : Type#1) -> A#4 ≡ (A : Type#1) -> A#3
[Type; String]#2 | [Type; String]#2 |-
x = (A : Type#1) -> A#3; (B : Type#1) -> x#3 ≡
(B : Type#1) -> (A : Type#1) -> A#4
[Type; String; x = (A : Type#1) -> A#3; B#3]#4 | [Type; String; B#3]#4 |-
x#3 ≡ (A : Type#1) -> A#4
| [Type; String]#4
| [Type; String; B#3]#4 |-
(A : Type#1) -> A#3 ≡ (A : Type#1) -> A#4
| [Type; String; A#4]#5
| [Type; String; B#3; A#4]#5 |-
A#3 ≡ A#4
| [Type; String; A#4]#5
| [Type; String; B#3; A#4]#5 |-
A#4 ≡ A#4
B#3#{((C : Type#1) -> C#4)}#3
received : B#3#{((C : Type#1) -> C#4)}#3
expected : (D : Type#1) -> D#4
((B : Type) -> B#3)#3
((x => x\0)[↑] N)[K] |-> x\0[N[K]]
(f : (B : Type) -> B#3) =>
(f#3 : ((B : Type) -> B#3)#3) ((C : Type#1) -> C#4)
B#3#(C : Type#1) -> C#4][↑]
B#3#{((C : Type#1) -> C#4)}#3
M : ((x : A) -> B)#{Δ}
----------------------
M N : B#{N}#{Δ}
M : ((x : A) -> B)#{Δ}
--------------------------
M N : ((x : A) => B)#{Δ} N
M : ((x : A) -> B)#{Δ}
--------------------------
M N : _T N
((x : A) => B)[x := N][Δ] ≡ ((x : _C) => _D)[x := N][_Φ]
M : ((x : A) -> B)[Δ] ((x : A) => B)[Δ] N ≡ _T N
-------------------------------------------------
M N : _T N
M N : _B#{x : _A := N}
M : ((x : A) -> B)#{Δ}
----------------------
M N : B#{Δ}#{←}#{N}
B#{N}#{Δ}
Γ |- M ⇔ B
-------------------
Γ, A |- M[↑] ⇔ B[↑]
Header
size | color | tag |
---|---|---|
2 | 5 |
color | tag | extend |
---|---|---|
2 | 5 | true |
type 'a list =
| Nil
| Cons of ('a * 'a list)
// to
List : (A : Data) -> A;
List = A =>
Nil | Cons (hd : A, tl : List A);
x = #debug 1;
// simple, single monad effects
Γ, x : A |- B : Type Γ, x : A |- E : (y : Type) -> Type
--------------------------------------------------------
Γ |- (x : A) -[E]> B : Type
// generalized unions
Γ |- A : Type Γ |- M : A Γ |- N : A
-------------------------------------
Γ |- M | N : A
// symbols instead of String would be dope
Log = K => (tag : String, witness : tag | "log" => K == Unit | _ => Never);
Read = K => (tag : String, witness : tag | "read" => K == String | _ => Never);
// handler just applies effect
handler : <A, E>(
init : () -[E]> A,
cb : <K>(eff : E K, k : (x : K) -> A) -> A
);
f : () -[Log | Read]> String = _;
() = handle f (<K>(eff : (Log | Read) K, k) -> _);
// what is a (Log | Read) K?
(Log | Read) K == (
tag : String,
witness :
tag
| "log" => K == Unit
| "read" => K == String
| _ => Never
)
(Log | Read) K
(x => Log x | x => Read x) K // eta
(x => Log x | Read x) K // extrusion
Log K | Read K // beta
// delta
(K => (tag : String, witness : tag | "log" => K == Unit | _ => Never)) K
| (K => (tag : String, witness : tag | "read" => K == String | _ => Never)) K
// beta
(tag : String, witness : tag | "log" => K == Unit | _ => Never)
| (tag : String, witness : tag | "read" => K == String | _ => Never)
// extrusion + pattern merge
(tag : String, witness : tag | "log" => K == Unit | "read" => K == String | _ => Never)
(Log | Read) K == (
tag : String,
witness :
tag
| "log" => K == Unit
| "read" => K == String
| _ => Never
)
// symbols instead of String would be dope
Log = K => (tag : Bool, tag (K == Unit) Never);
Read = K => (tag : Bool, tag Never (K == String));
// handler just applies effect
handler : <A, E>(
init : () -[E]> A,
cb : <K>(eff : E K, k : (x : K) -> A) -> A
);
f : () -[Log | Read]> String = _;
() = handle f (<K>(eff : (Log | Read) K, k) -> _);
// what is a (Log | Read) K?
(Log | Read) K == (
tag : String,
witness :
tag
| "log" => K == Unit
| "read" => K == String
| _ => Never
)
Log = K => (tag : Bool, tag (K == Unit) Never);
Read = K => (tag : Bool, tag Never (K == String));
(Log | Read) K
// eta
(x => Log x | x => Read x) K
// extrusion
(x => Log x | Read x) K
// beta
Log K | Read K
// delta
((K => (tag : Bool, tag (K == Unit) Never))
| (K => (tag : Bool, tag Never (K == String)))) K
// beta
(tag : Bool, tag (K == Unit) Never)
| (tag : Bool, tag Never (K == String))
// extrusion
(tag : Bool, (tag (K == Unit) Never) | (tag Never (K == String)))
// extrusion
(tag : Bool, (tag (K == Unit) | tag Never) (Never | K == String))
// extrusion
(tag : Bool, tag ((K == Unit) | Never) (Never | K == String))
// refute
(tag : Bool, tag (K == Unit) (K == String))
K M | K N |-> K (M | N)
M K | N K |-> (M | N) K
(tag (K == Unit) Never) | (tag Never (K == String))
((tag (K == Unit)) Never) | ((tag Never) (K == String))
((tag (K == Unit | Never)) Never) | ((tag (K == Unit | Never)) (K == String))
tag (K == Unit | Never) (Never | K == String);
tag (K == Unit) | tag Never |-> tag (K == Unit | Never)
(Log | Read) K == (tag : Bool, tag (K == Unit) (K == String))
M + N
M |-> VM N |-> VN
VM + VN
(b => x => b | true => x | false => 1) true (1 + 2 + 3 + 4)
(x => x + x + 10) (1 + 2 + 3 + 4)
10 + 10 + 10
(x => x + x + x) (1 + 2 + 3 + 4)
(1 + 2 + 3 + 4) + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4)
(x = 1 + 2 + 3 + 4; x + x + x)
(x => M) N |-> (x = N; M)
(x = N; C<x>) |-> (x = N; C<N>)
(x = 1 + 2 + 3 + 4; x + x + x)
(x = 1 + 2 + 3 + 4; (_ + x + x)<x>)
(x = 1 + 2 + 3 + 4; (_ + x + x)<1 + 2 + 3 + 4>)
(x = 1 + 2 + 3 + 4; (1 + 2 + 3 + 4) + x + x)
b => (x = 1 + 2 + 3 + 4; x + x + (b | true => x | false => 0))
Γ |- A : Type
--------------------------
Γ, x : A |- @typeof x == A
Γ, x : A |- B : Type
-------------------------------------------
Γ |- @typeof ((x : A) => M) == (x : A) -> B
Γ, x : A |- @typeof x : Type
---------------------
Γ |- x : @typeof x
M : ((x : A) -> B)[Δ] ((x : A) => B)[Δ] N ≡ _T N
-------------------------------------------------
M N : _T N
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
-----------------------------------------
Γ |- M N ⇒ ((x : A) => B) N
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
-----------------------------------------
Γ |- M N ⇒ ((x : A) => B) N
Γ |- M ⇒ ((x : A) -> B)[Δ] Γ |- N ⇐ A[Δ]
-----------------------------------------
Γ |- M N ⇒ (_T : (_ : _A) -> Type) N
M : ((x : _A) -> B)[Δ] N : _A[Δ]
-----------------------------------------
M N : (_T : (_x : _A) -> Type)[_Δ] N
M N : _x : _A[_Δ] = N; (_T : (_x : _A) -> Type)[_Δ[↑]]
M N : (_T : (_x : _A) -> Type)[_Δ] N
M : ((x : A) -> B)[Δ] N : A[Δ]
-----------------------------------------
M N : ((x : A) => B)[Δ] N
M : ((x : A) -> B)[Δ] N : A[Δ]
-------------------------------
M N : ((x : A) => B)[Δ] N
failwith "a"
x.y <- failwith "a"
setfield (goto 1)
x.y <- failwith "a"
map f l = map f l;
map f l =
l
| [] => []
| hd :: tl => f hd :: map f tl;
rec : <T, a>(f : (self : <b>(l : b < a) -> T b) -> T a) -> T a;
match x with
| l -> _
| exception Not_valid -> _
try