module Quox.Syntax.Qty import Quox.Pretty import Data.DPair %default total private commas : List (Doc HL) -> List (Doc HL) commas [] = [] commas [x] = [x] commas (x::xs) = (x <+> hl Delim ",") :: commas xs export %inline prettyQtyBinds : Pretty.HasEnv m => PrettyHL q => List q -> m (Doc HL) prettyQtyBinds = map ((hl Delim "@" <++>) . align . sep . commas) . traverse pretty0M public export interface Eq q => IsQty q where zero, one : q (+), (*) : q -> q -> q ||| true if bindings of this quantity will be erased ||| and must not be runtime relevant IsZero : q -> Type isZero : (pi : q) -> Dec (IsZero pi) zeroIsZero : IsZero zero ||| true if bindings of this quantity must be linear -- [fixme] is this needed for anything? IsOne : q -> Type isOne : (pi : q) -> Dec (IsOne pi) oneIsOne : IsOne one ||| ``p `Compat` q`` if it is ok for a binding of ||| quantity `q` to be used exactly `p` times. ||| e.g. ``1 `Compat` 1``, ``1 `Compat` ω`` Compat : q -> q -> Type compat : (pi, rh : q) -> Dec (pi `Compat` rh) ||| true if it is ok for this quantity to appear for the ||| subject of a typing judgement. this is about the ||| subject reduction stuff in atkey IsSubj : q -> Type isSubj : (pi : q) -> Dec (IsSubj pi) zeroIsSubj : IsSubj zero oneIsSubj : IsSubj one ||| true if it is ok for a global definition to have this ||| quantity. so not exact usage counts, maybe. IsGlobal : q -> Type isGlobal : (pi : q) -> Dec (IsGlobal pi) zeroIsGlobal : IsGlobal zero public export 0 SQty : (q : Type) -> IsQty q => Type SQty q = Subset q IsSubj public export %inline szero : IsQty q => SQty q szero = Element zero zeroIsSubj public export %inline sone : IsQty q => SQty q sone = Element one oneIsSubj public export 0 GQty : (q : Type) -> IsQty q => Type GQty q = Subset q IsGlobal public export %inline gzero : IsQty q => GQty q gzero = Element zero zeroIsGlobal