quox/lib/Quox/Syntax/Qty.idr

95 lines
2.4 KiB
Idris
Raw Normal View History

2021-07-20 16:05:19 -04:00
module Quox.Syntax.Qty
import Quox.Pretty
import Quox.Name
2023-01-09 17:43:23 -05:00
import public Quox.Decidable
2023-01-08 14:44:25 -05:00
import Data.DPair
2021-07-20 16:05:19 -04:00
2022-05-02 16:38:37 -04:00
%default total
2021-07-20 16:05:19 -04:00
private
commas : List (Doc HL) -> List (Doc HL)
2023-01-08 14:44:25 -05:00
commas [] = []
commas [x] = [x]
commas (x::xs) = (x <+> hl Delim ",") :: commas xs
2023-01-26 13:54:46 -05:00
private %inline
blobD : Pretty.HasEnv m => m (Doc HL)
blobD = hlF Delim $ ifUnicode "·" "@"
2021-07-20 16:05:19 -04:00
export %inline
prettyQtyBinds : Pretty.HasEnv m => PrettyHL q => PrettyHL a =>
List q -> a -> m (Doc HL)
prettyQtyBinds [] x = pretty0M x
prettyQtyBinds qtys x = pure $
hang 2 $ sep [aseparate comma !(traverse pretty0M qtys) <++> !blobD,
!(pretty0M x)]
2021-07-20 16:05:19 -04:00
public export
2023-01-08 14:44:25 -05:00
interface Eq q => IsQty q where
2021-09-09 17:51:45 -04:00
zero, one : q
(+), (*) : q -> q -> q
2023-01-08 14:44:25 -05:00
||| true if bindings of this quantity will be erased
||| and must not be runtime relevant
2023-01-09 17:43:23 -05:00
IsZero : Pred q
isZero : Dec1 IsZero
2023-01-08 14:44:25 -05:00
zeroIsZero : IsZero zero
||| ``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` ω``
2023-01-09 17:43:23 -05:00
Compat : Rel q
compat : Dec2 Compat
2023-01-08 14:44:25 -05:00
||| true if it is ok for this quantity to appear for the
2023-02-19 11:04:57 -05:00
||| subject of a typing judgement [@qtt, §2.3].
2023-01-09 17:43:23 -05:00
IsSubj : Pred q
isSubj : Dec1 IsSubj
zeroIsSubj : forall pi. IsZero pi -> IsSubj pi
2023-01-08 14:44:25 -05:00
oneIsSubj : IsSubj one
2023-01-09 17:43:55 -05:00
timesSubj : forall pi, rh. IsSubj pi -> IsSubj rh -> IsSubj (pi * rh)
2023-01-08 14:44:25 -05:00
||| true if it is ok for a global definition to have this
||| quantity. so not exact usage counts, maybe.
2023-01-09 17:43:23 -05:00
IsGlobal : Pred q
isGlobal : Dec1 IsGlobal
zeroIsGlobal : forall pi. IsZero pi -> IsGlobal zero
public export
2023-01-08 14:44:25 -05:00
0 SQty : (q : Type) -> IsQty q => Type
SQty q = Subset q IsSubj
2023-01-08 14:44:25 -05:00
public export %inline
szero : IsQty q => SQty q
szero = Element zero $ zeroIsSubj zeroIsZero
2023-01-08 14:44:25 -05:00
public export %inline
sone : IsQty q => SQty q
sone = Element one oneIsSubj
2022-08-22 04:07:46 -04:00
||| "σ ⨴ π"
|||
||| ``sg `subjMult` pi`` is equal to `pi` if it is zero, otherwise it
||| is equal to `sg`.
public export %inline
subjMult : IsQty q => SQty q -> q -> SQty q
subjMult sg pi = case isZero pi of
Yes y => Element pi $ zeroIsSubj y
No _ => sg
public export
2023-01-08 14:44:25 -05:00
0 GQty : (q : Type) -> IsQty q => Type
GQty q = Subset q IsGlobal
public export %inline
gzero : IsQty q => GQty q
gzero = Element zero $ zeroIsGlobal zeroIsZero
2023-03-13 14:33:09 -04:00
export %inline
globalToSubj : IsQty q => GQty q -> SQty q
globalToSubj q = if isYes $ isZero q.fst then szero else sone