quox/lib/Quox/Syntax/Term/Base.idr

266 lines
6.9 KiB
Idris
Raw Normal View History

2022-04-23 18:21:30 -04:00
module Quox.Syntax.Term.Base
import public Quox.Syntax.Var
import public Quox.Syntax.Shift
import public Quox.Syntax.Subst
import public Quox.Syntax.Qty
import public Quox.Syntax.Dim
import public Quox.Name
import public Quox.Context
2022-04-23 18:21:30 -04:00
import Quox.Pretty
import public Data.DPair
import Data.List
import Data.Maybe
import Data.Nat
import public Data.So
import Data.String
import public Data.SortedMap
import public Data.SortedSet
2022-04-23 18:21:30 -04:00
%default total
public export
0 TermLike : Type
2023-04-01 13:16:43 -04:00
TermLike = Nat -> Nat -> Type
public export
0 TSubstLike : Type
2023-04-01 13:16:43 -04:00
TSubstLike = Nat -> Nat -> Nat -> Type
2023-03-05 10:48:29 -05:00
public export
0 Universe : Type
Universe = Nat
public export
0 TagVal : Type
TagVal = String
2022-04-23 18:21:30 -04:00
infixl 8 :#
2023-01-20 20:34:28 -05:00
infixl 9 :@, :%
2022-04-23 18:21:30 -04:00
mutual
public export
0 TSubst : TSubstLike
2023-04-01 13:16:43 -04:00
TSubst d = Subst $ Elim d
2022-04-23 18:21:30 -04:00
2023-04-01 13:16:43 -04:00
||| first argument `d` is dimension scope size;
||| second `n` is term scope size
2022-04-23 18:21:30 -04:00
public export
data Term : TermLike where
2022-04-23 18:21:30 -04:00
||| type of types
2023-04-01 13:16:43 -04:00
TYPE : (l : Universe) -> Term d n
2022-04-23 18:21:30 -04:00
||| function type
2023-04-01 13:16:43 -04:00
Pi : (qty : Qty) -> (arg : Term d n) ->
(res : ScopeTerm d n) -> Term d n
2022-04-23 18:21:30 -04:00
||| function term
2023-04-01 13:16:43 -04:00
Lam : (body : ScopeTerm d n) -> Term d n
2022-04-23 18:21:30 -04:00
2023-01-26 13:54:46 -05:00
||| pair type
2023-04-01 13:16:43 -04:00
Sig : (fst : Term d n) -> (snd : ScopeTerm d n) -> Term d n
2023-01-26 13:54:46 -05:00
||| pair value
2023-04-01 13:16:43 -04:00
Pair : (fst, snd : Term d n) -> Term d n
2023-01-26 13:54:46 -05:00
||| enumeration type
2023-04-01 13:16:43 -04:00
Enum : (cases : SortedSet TagVal) -> Term d n
||| enumeration value
2023-04-01 13:16:43 -04:00
Tag : (tag : TagVal) -> Term d n
2023-01-20 20:34:28 -05:00
||| equality type
2023-04-01 13:16:43 -04:00
Eq : (ty : DScopeTerm d n) -> (l, r : Term d n) -> Term d n
2023-01-20 20:34:28 -05:00
||| equality term
2023-04-01 13:16:43 -04:00
DLam : (body : DScopeTerm d n) -> Term d n
2023-01-20 20:34:28 -05:00
2023-03-26 08:40:54 -04:00
||| natural numbers (temporary until 𝐖 gets added)
2023-04-01 13:16:43 -04:00
Nat : Term d n
2023-03-26 08:40:54 -04:00
-- [todo] can these be elims?
2023-04-01 13:16:43 -04:00
Zero : Term d n
Succ : (p : Term d n) -> Term d n
2023-03-26 08:40:54 -04:00
2023-03-31 13:11:35 -04:00
||| "box" (package a value up with a certain quantity)
2023-04-01 13:16:43 -04:00
BOX : (qty : Qty) -> (ty : Term d n) -> Term d n
Box : (val : Term d n) -> Term d n
2023-03-31 13:11:35 -04:00
2022-04-23 18:21:30 -04:00
||| elimination
2023-04-01 13:16:43 -04:00
E : (e : Elim d n) -> Term d n
2022-04-23 18:21:30 -04:00
||| term closure/suspended substitution
2023-04-01 13:16:43 -04:00
CloT : (tm : Term d from) -> (th : Lazy (TSubst d from to)) ->
Term d to
2022-04-23 18:21:30 -04:00
||| dimension closure/suspended substitution
2023-04-01 13:16:43 -04:00
DCloT : (tm : Term dfrom n) -> (th : Lazy (DSubst dfrom dto)) ->
Term dto n
2022-04-23 18:21:30 -04:00
||| first argument `d` is dimension scope size, second `n` is term scope size
public export
data Elim : TermLike where
2022-04-23 18:21:30 -04:00
||| free variable
2023-04-01 13:16:43 -04:00
F : (x : Name) -> Elim d n
2022-04-23 18:21:30 -04:00
||| bound variable
2023-04-01 13:16:43 -04:00
B : (i : Var n) -> Elim d n
2022-04-23 18:21:30 -04:00
||| term application
2023-04-01 13:16:43 -04:00
(:@) : (fun : Elim d n) -> (arg : Term d n) -> Elim d n
2022-04-23 18:21:30 -04:00
2023-01-26 13:54:46 -05:00
||| pair destruction
|||
2023-02-22 01:40:19 -05:00
||| `CasePair 𝜋 𝑒 ([𝑟], 𝐴) ([𝑥, 𝑦], 𝑡)` is
2023-03-04 15:02:51 -05:00
||| `𝐜𝐚𝐬𝐞 𝜋 · 𝑒 𝐫𝐞𝐭𝐮𝐫𝐧 𝑟𝐴 𝐨𝐟 { (𝑥, 𝑦) ⇒ 𝑡 }`
2023-04-01 13:16:43 -04:00
CasePair : (qty : Qty) -> (pair : Elim d n) ->
(ret : ScopeTerm d n) ->
(body : ScopeTermN 2 d n) ->
Elim d n
2023-01-26 13:54:46 -05:00
||| enum matching
2023-04-01 13:16:43 -04:00
CaseEnum : (qty : Qty) -> (tag : Elim d n) ->
(ret : ScopeTerm d n) ->
(arms : CaseEnumArms d n) ->
Elim d n
2023-03-26 08:40:54 -04:00
||| nat matching
2023-04-01 13:16:43 -04:00
CaseNat : (qty, qtyIH : Qty) -> (nat : Elim d n) ->
(ret : ScopeTerm d n) ->
(zero : Term d n) ->
(succ : ScopeTermN 2 d n) ->
Elim d n
2023-03-31 13:11:35 -04:00
||| unboxing
2023-04-01 13:16:43 -04:00
CaseBox : (qty : Qty) -> (box : Elim d n) ->
(ret : ScopeTerm d n) ->
(body : ScopeTerm d n) ->
Elim d n
2023-03-31 13:11:35 -04:00
2023-01-20 20:34:28 -05:00
||| dim application
2023-04-01 13:16:43 -04:00
(:%) : (fun : Elim d n) -> (arg : Dim d) -> Elim d n
2023-01-20 20:34:28 -05:00
2022-04-23 18:21:30 -04:00
||| type-annotated term
2023-04-01 13:16:43 -04:00
(:#) : (tm, ty : Term d n) -> Elim d n
2022-04-23 18:21:30 -04:00
2023-04-03 11:46:23 -04:00
||| match on types (needed for coercions :mario_flop:)
TypeCase : (ty : Elim d n) ->
(ret : Term d n) ->
(univ : Term d n) ->
(pi : ScopeTermN 2 d n) ->
(sig : ScopeTermN 2 d n) ->
(enum : Term d n) ->
(eq : ScopeTermN 5 d n) ->
(nat : Term d n) ->
(box : ScopeTerm d n) ->
Elim d n
2022-04-23 18:21:30 -04:00
||| term closure/suspended substitution
2023-04-01 13:16:43 -04:00
CloE : (el : Elim d from) -> (th : Lazy (TSubst d from to)) ->
Elim d to
2022-04-23 18:21:30 -04:00
||| dimension closure/suspended substitution
2023-04-01 13:16:43 -04:00
DCloE : (el : Elim dfrom n) -> (th : Lazy (DSubst dfrom dto)) ->
Elim dto n
2022-04-23 18:21:30 -04:00
public export
2023-02-22 01:40:19 -05:00
0 CaseEnumArms : TermLike
2023-04-01 13:16:43 -04:00
CaseEnumArms d n = SortedMap TagVal (Term d n)
2022-04-23 18:21:30 -04:00
2023-02-22 01:40:19 -05:00
||| a scoped term with names
2022-04-23 18:21:30 -04:00
public export
2023-02-22 01:40:19 -05:00
record Scoped (s : Nat) (f : Nat -> Type) (n : Nat) where
constructor S
names : NContext s
2023-02-22 01:40:19 -05:00
body : ScopedBody s f n
2023-01-22 21:22:50 -05:00
public export
2023-02-22 01:40:19 -05:00
data ScopedBody : Nat -> (Nat -> Type) -> Nat -> Type where
Y : (body : f (s + n)) -> ScopedBody s f n
N : (body : f n) -> ScopedBody s f n
2023-01-22 21:22:50 -05:00
public export
2023-02-22 01:40:19 -05:00
0 ScopeTermN, DScopeTermN : Nat -> TermLike
2023-04-01 13:16:43 -04:00
ScopeTermN s d n = Scoped s (Term d) n
DScopeTermN s d n = Scoped s (\d => Term d n) d
2023-02-22 01:40:19 -05:00
public export
0 ScopeTerm, DScopeTerm : TermLike
ScopeTerm = ScopeTermN 1
2023-01-22 21:22:50 -05:00
DScopeTerm = DScopeTermN 1
2022-04-23 18:21:30 -04:00
%name Term s, t, r
%name Elim e, f
2023-02-22 01:40:19 -05:00
%name Scoped body
%name ScopedBody body
2022-04-23 18:21:30 -04:00
2023-02-25 09:24:45 -05:00
||| scope which ignores all its binders
public export %inline
SN : {s : Nat} -> f n -> Scoped s f n
SN = S (replicate s Unused) . N
2023-02-25 09:24:45 -05:00
||| scope which uses its binders
public export %inline
SY : NContext s -> f (s + n) -> Scoped s f n
2023-02-25 09:24:45 -05:00
SY ns = S ns . Y
public export %inline
name : Scoped 1 f n -> BaseName
name (S [< x] _) = x
public export %inline
(.name) : Scoped 1 f n -> BaseName
s.name = name s
2023-02-25 09:24:45 -05:00
||| more convenient Pi
public export %inline
2023-04-01 13:16:43 -04:00
Pi_ : (qty : Qty) -> (x : BaseName) ->
(arg : Term d n) -> (res : Term d (S n)) -> Term d n
Pi_ {qty, x, arg, res} = Pi {qty, arg, res = S [< x] $ Y res}
2023-02-25 09:24:45 -05:00
2023-01-20 20:34:28 -05:00
||| non dependent function type
2022-04-27 14:06:39 -04:00
public export %inline
2023-04-01 13:16:43 -04:00
Arr : (qty : Qty) -> (arg, res : Term d n) -> Term d n
2023-02-25 09:24:45 -05:00
Arr {qty, arg, res} = Pi {qty, arg, res = SN res}
2022-04-27 14:06:39 -04:00
2023-02-25 09:24:45 -05:00
||| more convenient Sig
2023-01-20 20:34:28 -05:00
public export %inline
2023-04-01 13:16:43 -04:00
Sig_ : (x : BaseName) -> (fst : Term d n) ->
(snd : Term d (S n)) -> Term d n
Sig_ {x, fst, snd} = Sig {fst, snd = S [< x] $ Y snd}
2023-01-20 20:34:28 -05:00
2023-02-12 15:30:08 -05:00
||| non dependent pair type
public export %inline
2023-04-01 13:16:43 -04:00
And : (fst, snd : Term d n) -> Term d n
2023-02-25 09:24:45 -05:00
And {fst, snd} = Sig {fst, snd = SN snd}
||| more convenient Eq
public export %inline
2023-04-01 13:16:43 -04:00
Eq_ : (i : BaseName) -> (ty : Term (S d) n) ->
(l, r : Term d n) -> Term d n
Eq_ {i, ty, l, r} = Eq {ty = S [< i] $ Y ty, l, r}
2023-02-25 09:24:45 -05:00
||| non dependent equality type
public export %inline
2023-04-01 13:16:43 -04:00
Eq0 : (ty, l, r : Term d n) -> Term d n
2023-02-25 09:24:45 -05:00
Eq0 {ty, l, r} = Eq {ty = SN ty, l, r}
2023-02-12 15:30:08 -05:00
2022-04-23 18:21:30 -04:00
||| same as `F` but as a term
public export %inline
2023-04-01 13:16:43 -04:00
FT : Name -> Term d n
2022-04-23 18:21:30 -04:00
FT = E . F
||| abbreviation for a bound variable like `BV 4` instead of
||| `B (VS (VS (VS (VS VZ))))`
public export %inline
2023-04-01 13:16:43 -04:00
BV : (i : Nat) -> (0 _ : LT i n) => Elim d n
2022-04-23 18:21:30 -04:00
BV i = B $ V i
||| same as `BV` but as a term
public export %inline
2023-04-01 13:16:43 -04:00
BVT : (i : Nat) -> (0 _ : LT i n) => Term d n
2022-04-23 18:21:30 -04:00
BVT i = E $ BV i
2023-03-26 10:14:58 -04:00
2023-03-26 10:15:19 -04:00
public export
2023-04-01 13:16:43 -04:00
makeNat : Nat -> Term d n
2023-03-26 10:15:19 -04:00
makeNat 0 = Zero
makeNat (S k) = Succ $ makeNat k
2023-03-26 10:14:58 -04:00
public export
2023-04-01 13:16:43 -04:00
enum : List TagVal -> Term d n
2023-03-26 10:14:58 -04:00
enum = Enum . SortedSet.fromList