{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.PTS.Value (
Value,
ValueIntro (..),
ValueElim (..),
pureValueIntro,
pureValueElim,
mapValueIntroError,
valueApp,
errorlessValueIntro,
errorlessValueIntro',
errorlessValueElim,
errorlessValueElim',
#if LANGUAGE_PTS_HAS_SIGMA
valueMatch,
#endif
#if LANGUAGE_PTS_HAS_EQUALITY
valueJ,
#endif
#if LANGUAGE_PTS_HAS_PROP
valueAbsurd,
#endif
#if LANGUAGE_PTS_HAS_BOOL
valueBoolElim,
#if LANGUAGE_PTS_HAS_BOOL_PRIM
valueAnd,
#endif
#endif
#if LANGUAGE_PTS_HAS_NAT
valueNatElim,
#if LANGUAGE_PTS_HAS_NAT_PRIM
valuePlus,
valueTimes,
#endif
#endif
#if LANGUAGE_PTS_HAS_QUARKS
valueQuarkElim,
#endif
pppIntro,
pppElim,
) where
import Control.Lens (review)
import Control.Monad (ap, void)
import Data.Functor.Classes
import Data.Functor.Identity (Identity (..))
import Data.String (IsString (..))
import Data.Void (Void)
import Text.Show.Extras
import Language.PTS.Bound
import Language.PTS.Error
import Language.PTS.Pretty
import Language.PTS.Specification
import Language.PTS.Sym
#ifdef LANGUAGE_PTS_HAS_NAT
import Numeric.Natural
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
import Data.Set (Set)
import Data.Map (Map)
import qualified Data.Set as Set
import qualified Data.Map as Map
#endif
type Value s = ValueIntro Err s Sym
data ValueIntro err s a
= ValueLam IrrSym (ValueIntro err s a) (Scope IrrSym (ValueIntro err s) a)
| ValueCoerce (ValueElim err s a)
| ValueSort s
| ValuePi IrrSym (ValueIntro err s a) (Scope IrrSym (ValueIntro err s) a)
| ValueErr err
#ifdef LANGUAGE_PTS_HAS_SIGMA
| ValueSigma IrrSym (ValueIntro err s a) (Scope IrrSym (ValueIntro err s) a)
| ValuePair (ValueIntro err s a) (ValueIntro err s a)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
| ValueEquality (ValueIntro err s a) (ValueIntro err s a) (ValueIntro err s a)
| ValueRefl
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
| ValueUnit
| ValueI
| ValueEmpty
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
| ValueBool
| ValueTrue
| ValueFalse
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
| ValueNat
| ValueNatZ
| ValueNatS (ValueIntro err s a)
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
| ValueHadron (Set Sym)
| ValueQuark Sym
#endif
deriving (Functor, Foldable, Traversable)
data ValueElim err s a
= ValueApp (ValueElim err s a) (ValueIntro err s a)
| ValueVar a
#ifdef LANGUAGE_PTS_HAS_SIGMA
| ValueMatch (ValueElim err s a) IrrSym IrrSym (Scope IrrSym2 (ValueIntro err s) a)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
| ValueJ (V3 IrrSym)
(ValueIntro err s a)
(Scope IrrSym3 (ValueIntro err s) a)
(ValueIntro err s a)
(ValueIntro err s a)
(ValueIntro err s a)
(ValueElim err s a)
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
| ValueAbsurd (ValueIntro err s a) (ValueElim err s a)
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
| ValueBoolElim IrrSym (Scope IrrSym (ValueIntro err s) a) (ValueIntro err s a) (ValueIntro err s a) (ValueElim err s a)
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
| ValueAnd (ValueElim err s a) (ValueElim err s a)
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
| ValueNatElim IrrSym (Scope IrrSym (ValueIntro err s) a) (ValueIntro err s a) (ValueIntro err s a) (ValueElim err s a)
#ifdef LANGUAGE_PTS_HAS_NAT_PRIM
| ValuePlus (ValueElim err s a) (ValueElim err s a)
| ValueTimes (ValueElim err s a) (ValueElim err s a)
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
| ValueQuarkElim IrrSym (Scope IrrSym (ValueIntro err s) a) (Map Sym (ValueIntro err s a)) (ValueElim err s a)
#endif
#ifdef LANGUAGE_PTS_HAS_FIX
| ValueFix (ValueElim err s a)
#endif
deriving (Functor, Foldable, Traversable)
instance IsString a => IsString (ValueIntro err s a) where
fromString = ValueCoerce . fromString
instance IsString a => IsString (ValueElim err s a) where
fromString = ValueVar . fromString
instance (PrettyPrec err, AsErr err, Specification s) => Applicative (ValueIntro err s) where
pure = pureValueIntro
(<*>) = ap
instance (PrettyPrec err, AsErr err, Specification s) => Monad (ValueIntro err s) where
return = pure
ValueSort s >>= _ = ValueSort s
ValueLam n t b >>= k = ValueLam n (t >>= k) (b >>>= k)
ValuePi n a b >>= k = ValuePi n (a >>= k) (b >>>= k)
ValueCoerce u >>= k = valueAppBind u k
ValueErr err >>= _ = ValueErr err
#ifdef LANGUAGE_PTS_HAS_SIGMA
ValueSigma x a b >>= k = ValueSigma x (a >>= k) (b >>>= k)
ValuePair a b >>= k = ValuePair (a >>= k) (b >>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
ValueEquality a x y >>= k = ValueEquality (a >>= k) (x >>= k) (y >>= k)
ValueRefl >>= _ = ValueRefl
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
ValueUnit >>= _ = ValueUnit
ValueI >>= _ = ValueI
ValueEmpty >>= _ = ValueEmpty
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
ValueBool >>= _ = ValueBool
ValueTrue >>= _ = ValueTrue
ValueFalse >>= _ = ValueFalse
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
ValueNat >>= _ = ValueNat
ValueNatZ >>= _ = ValueNatZ
ValueNatS n >>= k = ValueNatS (n >>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
ValueHadron ls >>= _ = ValueHadron ls
ValueQuark l >>= _ = ValueQuark l
#endif
valueAppBind
:: (PrettyPrec err, AsErr err, Specification s)
=> ValueElim err s a
-> (a -> ValueIntro err s b)
-> ValueIntro err s b
valueAppBind (ValueVar a) k = k a
valueAppBind (ValueApp f x) k =
valueApp (valueAppBind f k) (x >>= k)
#ifdef LANGUAGE_PTS_HAS_SIGMA
valueAppBind (ValueMatch p x y b) k = valueMatch
(valueAppBind p k)
x y
(b >>>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
valueAppBind (ValueJ v3 a p r u v w) k = valueJ v3
(a >>= k)
(p >>>= k)
(r >>= k)
(u >>= k)
(v >>= k)
(valueAppBind w k)
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
valueAppBind (ValueAbsurd a x) k = valueAbsurd (a >>= k) (valueAppBind x k)
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
valueAppBind (ValueBoolElim x p t f b) k =
valueBoolElim x (p >>>= k) (t >>= k) (f >>= k) (valueAppBind b k)
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
valueAppBind (ValueAnd x y) k =
valueAnd (valueAppBind x k) (valueAppBind y k)
#endif
#endif
#if LANGUAGE_PTS_HAS_NAT
valueAppBind (ValueNatElim x a z s n) k =
valueNatElim x (a >>>= k) (z >>= k) (s >>= k) (valueAppBind n k)
#if LANGUAGE_PTS_HAS_NAT_PRIM
valueAppBind (ValuePlus x y) k =
valuePlus (valueAppBind x k) (valueAppBind y k)
valueAppBind (ValueTimes x y) k =
valueTimes (valueAppBind x k) (valueAppBind y k)
#endif
#endif
#if LANGUAGE_PTS_HAS_QUARKS
valueAppBind (ValueQuarkElim x p ls l) k =
valueQuarkElim x (p >>>= k) (fmap (>>= k) ls) (valueAppBind l k)
#endif
#if LANGUAGE_PTS_HAS_FIX
valueAppBind (ValueFix f) k = case valueAppBind f k of
ValueCoerce f' -> ValueCoerce (ValueFix f')
f'@(ValueLam _n b) -> instantiate1 f' b
ValueErr err -> ValueErr err
f' -> ValueErr $ review _Err $ ApplyPanic (pppValueIntro 0 f')
#endif
instance (PrettyPrec err, AsErr err, Specification s) => Applicative (ValueElim err s) where
pure = pureValueElim
(<*>) = ap
instance (PrettyPrec err, AsErr err, Specification s) => Monad (ValueElim err s) where
return = pure
ValueVar x >>= k = k x
ValueApp f x >>= k = ValueApp (f >>= k) (valueBind x k)
#ifdef LANGUAGE_PTS_HAS_SIGMA
ValueMatch p x y b >>= k = ValueMatch (p >>= k) x y
(valueBindScope b k)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
ValueJ v3 a p r u v w >>= k = ValueJ v3
(valueBind a k)
(valueBindScope p k)
(valueBind r k)
(valueBind u k)
(valueBind v k)
(w >>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
ValueAbsurd a x >>= k = ValueAbsurd (valueBind a k) (x >>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
ValueBoolElim x a t f b >>= k = ValueBoolElim x
(valueBindScope a k)
(valueBind t k)
(valueBind f k)
(b >>= k)
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
ValueAnd x y >>= k = ValueAnd (x >>= k) (y >>= k)
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
ValueNatElim x a z s n >>= k = ValueNatElim x
(valueBindScope a k)
(valueBind z k)
(valueBind s k)
(n >>= k)
#if LANGUAGE_PTS_HAS_NAT_PRIM
ValuePlus x y >>= k = ValuePlus (x >>= k) (y >>= k)
ValueTimes x y >>= k = ValueTimes (x >>= k) (y >>= k)
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
ValueQuarkElim x p ls l >>= k = ValueQuarkElim x
(valueBindScope p k)
(fmap (`valueBind` k) ls)
(l >>= k)
#endif
#ifdef LANGUAGE_PTS_HAS_FIX
ValueFix f >>= k = ValueFix (f >>= k)
#endif
#if defined(LANGUAGE_PTS_HAS_SIGMA) || defined(LANGUAGE_PTS_HAS_EQUALITY) || defined(LANGUAGE_PTS_HAS_BOOL) || defined(LANGUAGE_PTS_HAS_NAT) || defined(LANGUAGE_PTS_HAS_QUARKS)
valueBindScope
:: (AsErr err, Specification s, PrettyPrec err)
=> Scope n (ValueIntro err s) a
-> (a -> ValueElim err s b)
-> Scope n (ValueIntro err s) b
valueBindScope s k = toScope $ valueBind (fromScope s) $ unvar (return . B) (fmap F . k)
#endif
instance (PrettyPrec err, AsErr err, Specification s) => Module (ValueIntro err s) (ValueElim err s) where
(>>==) = valueBind
valueBind
:: (PrettyPrec err, AsErr err, Specification s)
=> ValueIntro err s a -> (a -> ValueElim err s b) -> ValueIntro err s b
valueBind (ValueSort s) _ = ValueSort s
valueBind (ValueCoerce e) k = ValueCoerce (e >>= k)
valueBind (ValueLam n t b) k = ValueLam n (valueBind t k) (b >>>= ValueCoerce . k)
valueBind (ValuePi n a b) k = ValuePi n (a >>= ValueCoerce . k) (b >>>= ValueCoerce . k)
valueBind (ValueErr err) _ = ValueErr err
#if LANGUAGE_PTS_HAS_SIGMA
valueBind (ValueSigma x a b) k = ValueSigma x (a >>= ValueCoerce . k) (b >>>= ValueCoerce . k)
valueBind (ValuePair a b) k = ValuePair (a >>= ValueCoerce . k) (b >>= ValueCoerce . k)
#endif
#if LANGUAGE_PTS_HAS_EQUALITY
valueBind (ValueEquality a x y) k = ValueEquality (a >>= ValueCoerce . k) (x >>= ValueCoerce . k) (y >>= ValueCoerce . k)
valueBind ValueRefl _ = ValueRefl
#endif
#if LANGUAGE_PTS_HAS_PROP
valueBind ValueUnit _ = ValueUnit
valueBind ValueI _ = ValueI
valueBind ValueEmpty _ = ValueEmpty
#endif
#if LANGUAGE_PTS_HAS_BOOL
valueBind ValueBool _ = ValueBool
valueBind ValueTrue _ = ValueTrue
valueBind ValueFalse _ = ValueFalse
#if LANGUAGE_PTS_HAS_BOOL_NAT
valueBInd (ValueAnd x y) k = ValueAnd (x >>= ValueCoerce . k) (y >>= ValueCoerce . k)
#endif
#endif
#if LANGUAGE_PTS_HAS_NAT
valueBind ValueNat _ = ValueNat
valueBind ValueNatZ _ = ValueNatZ
valueBind (ValueNatS n) k = ValueNatS (n >>= ValueCoerce . k)
#endif
#if LANGUAGE_PTS_HAS_QUARKS
valueBind (ValueHadron ls) _ = ValueHadron ls
valueBind (ValueQuark l) _ = ValueQuark l
#endif
pureValueIntro :: a -> ValueIntro err s a
pureValueIntro = ValueCoerce . pureValueElim
pureValueElim :: a -> ValueElim err s a
pureValueElim = ValueVar
valueApp
:: (PrettyPrec err, AsErr err, Specification s)
=> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueApp (ValueCoerce f) x = ValueCoerce (ValueApp f x)
valueApp (ValueLam _n _t f) x = instantiate1 x f
valueApp (ValueErr err) _ = ValueErr err
valueApp f' _ = ValueErr $ review _Err $ ApplyPanic "apply" $ ppp0 $ void f'
#if LANGUAGE_PTS_HAS_BOOL
valueBoolElim
:: (Specification s, AsErr err, PrettyPrec err)
=> IrrSym
-> Scope IrrSym (ValueIntro err s) a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueBoolElim x p t f = go where
go (ValueCoerce b) = ValueCoerce (ValueBoolElim x p t f b)
go ValueTrue = t
go ValueFalse = f
go (ValueErr err) = ValueErr err
go b = ValueErr $ review _Err $
ApplyPanic "𝔹-elim" $ ppp0 x <+> ppp0 (void t) <+> ppp0 (void f) <+> ppp0 (void b)
#if LANGUAGE_PTS_HAS_BOOL_PRIM
valueAnd
:: (Specification s, AsErr err, PrettyPrec err)
=> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueAnd ValueTrue ValueTrue = ValueTrue
valueAnd ValueTrue ValueFalse = ValueFalse
valueAnd ValueFalse ValueTrue = ValueFalse
valueAnd ValueFalse ValueFalse = ValueFalse
valueAnd (ValueErr err) _ = ValueErr err
valueAnd _ (ValueErr err) = ValueErr err
valueAnd ValueTrue (ValueCoerce y) = ValueCoerce y
valueAnd ValueFalse (ValueCoerce _) = ValueFalse
valueAnd (ValueCoerce x) ValueTrue = ValueCoerce x
valueAnd (ValueCoerce _) ValueFalse = ValueFalse
valueAnd (ValueCoerce x) (ValueCoerce y) = ValueCoerce (ValueAnd x y)
valueAnd x y = ValueErr $ review _Err $ ApplyPanic "𝔹-and" $ ppp0 (void x, void y)
#endif
#endif
#if LANGUAGE_PTS_HAS_NAT
valueNatElim
:: (Specification s, AsErr err, PrettyPrec err)
=> IrrSym
-> Scope IrrSym (ValueIntro err s) a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueNatElim x p z s = go where
go (ValueCoerce n) = ValueCoerce (ValueNatElim x p z s n)
go ValueNatZ = z
go (ValueNatS n) = s `valueApp` n `valueApp` go n
go n' = ValueErr $ review _Err $ ApplyPanic "ℕ-elim" $ ppp0 (void n')
#if LANGUAGE_PTS_HAS_NAT_PRIM
valuePlus
:: (Specification s, AsErr err, PrettyPrec err)
=> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valuePlus ValueNatZ m = m
valuePlus (ValueNatS n) m = ValueNatS (valuePlus n m)
valuePlus n ValueNatZ = n
valuePlus n (ValueNatS m) = ValueNatS (valuePlus n m)
valuePlus (ValueCoerce n) (ValueCoerce m) = ValueCoerce (ValuePlus n m)
valuePlus (ValueErr err) _ = ValueErr err
valuePlus _ (ValueErr err) = ValueErr err
valuePlus x y = ValueErr $ review _Err $ ApplyPanic "ℕ-plus" $ ppp0 (void x, void y)
valueTimes
:: (Specification s, AsErr err, PrettyPrec err)
=> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueTimes ValueNatZ _ = ValueNatZ
valueTimes (ValueNatS n) m = valuePlus m (valueTimes n m)
valueTimes _ ValueNatZ = ValueNatZ
valueTimes n (ValueNatS m) = valuePlus n (valueTimes n m)
valueTimes (ValueCoerce n) (ValueCoerce m) = ValueCoerce (ValueTimes n m)
valueTimes (ValueErr err) _ = ValueErr err
valueTimes _ (ValueErr err) = ValueErr err
valueTimes x y = ValueErr $ review _Err $ ApplyPanic "ℕ-times" $ ppp0 (void x, void y)
#endif
#endif
#if LANGUAGE_PTS_HAS_QUARKS
valueQuarkElim
:: (Specification s, AsErr err, PrettyPrec err)
=> IrrSym
-> Scope IrrSym (ValueIntro err s) a
-> Map Sym (ValueIntro err s a)
-> ValueIntro err s a
-> ValueIntro err s a
valueQuarkElim x p ls = go where
go (ValueCoerce l) = ValueCoerce (ValueQuarkElim x p ls l)
go (ValueErr err) = ValueErr err
go (ValueQuark l)
| Just v <- Map.lookup l ls = v
| otherwise = ValueErr $ review _Err $ SomeErr $ show (l, Map.keys ls)
go l = ValueErr $ review _Err $
ApplyPanic "L-elim" $ ppp0 (void l)
#endif
#ifdef LANGUAGE_PTS_HAS_SIGMA
valueMatch
:: (Specification s, AsErr err, PrettyPrec err)
=> ValueIntro err s a
-> IrrSym
-> IrrSym
-> Scope IrrSym2 (ValueIntro err s) a
-> ValueIntro err s a
valueMatch (ValuePair a b) _ _ body = instantiate2 a b body
valueMatch (ValueErr err) _ _ _ = ValueErr err
valueMatch (ValueCoerce p) x y body = ValueCoerce (ValueMatch p x y body)
valueMatch p _ _ _ = ValueErr $ review _Err $ ApplyPanic "match" $ ppp0 (void p)
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
valueJ
:: (Specification s, AsErr err, PrettyPrec err)
=> V3 IrrSym
-> ValueIntro err s a
-> Scope IrrSym3 (ValueIntro err s) a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueJ v3 a p r u v w = case w of
ValueRefl -> valueApp r u
ValueErr err -> ValueErr err
ValueCoerce w' -> ValueCoerce (ValueJ v3 a p r u v w')
_ -> ValueErr $ review _Err $ ApplyPanic "j" $ ppp0 (void w)
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
valueAbsurd
:: (Specification s, AsErr err, PrettyPrec err)
=> ValueIntro err s a
-> ValueIntro err s a
-> ValueIntro err s a
valueAbsurd a (ValueCoerce x) = ValueCoerce (ValueAbsurd a x)
valueAbsurd _ (ValueErr err) = ValueErr err
valueAbsurd _ v = ValueErr $ review _Err $ ApplyPanic "absurd" $ ppp0 (void v)
#endif
mapValueIntroError :: (err -> err') -> ValueIntro err s a -> ValueIntro err' s a
mapValueIntroError f = runIdentity . traverseErrValueIntro (Identity . f)
traverseErrValueIntro :: Applicative f => (err -> f err') -> ValueIntro err s a -> f (ValueIntro err' s a)
traverseErrValueIntro f (ValueErr err) = ValueErr <$> f err
traverseErrValueIntro _ (ValueSort s) = pure (ValueSort s)
traverseErrValueIntro f (ValueCoerce e) = ValueCoerce <$> traverseErrValueElim f e
traverseErrValueIntro f (ValueLam n t b) = ValueLam n
<$> traverseErrValueIntro f t
<*> transverseScope (traverseErrValueIntro f) b
traverseErrValueIntro f (ValuePi n a b) = ValuePi n
<$> traverseErrValueIntro f a
<*> transverseScope (traverseErrValueIntro f) b
#ifdef LANGUAGE_PTS_HAS_SIGMA
traverseErrValueIntro f (ValueSigma x a b) = ValueSigma x
<$> traverseErrValueIntro f a
<*> transverseScope (traverseErrValueIntro f) b
traverseErrValueIntro f (ValuePair a b) = ValuePair
<$> traverseErrValueIntro f a
<*> traverseErrValueIntro f b
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
traverseErrValueIntro f (ValueEquality a x y) = ValueEquality
<$> traverseErrValueIntro f a
<*> traverseErrValueIntro f x
<*> traverseErrValueIntro f y
traverseErrValueIntro _ ValueRefl = pure ValueRefl
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
traverseErrValueIntro _ ValueUnit = pure ValueUnit
traverseErrValueIntro _ ValueI = pure ValueI
traverseErrValueIntro _ ValueEmpty = pure ValueEmpty
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
traverseErrValueIntro _ ValueBool = pure ValueBool
traverseErrValueIntro _ ValueTrue = pure ValueTrue
traverseErrValueIntro _ ValueFalse = pure ValueFalse
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
traverseErrValueIntro _ ValueNat = pure ValueNat
traverseErrValueIntro _ ValueNatZ = pure ValueNatZ
traverseErrValueIntro f (ValueNatS n) = ValueNatS <$> traverseErrValueIntro f n
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
traverseErrValueIntro _ (ValueHadron ls) = pure (ValueHadron ls)
traverseErrValueIntro _ (ValueQuark l) = pure (ValueQuark l)
#endif
traverseErrValueElim :: Applicative f => (err -> f err') -> ValueElim err s a -> f (ValueElim err' s a)
traverseErrValueElim _ (ValueVar a) = pure (ValueVar a)
traverseErrValueElim f (ValueApp g x) = ValueApp <$> traverseErrValueElim f g <*> traverseErrValueIntro f x
#ifdef LANGUAGE_PTS_HAS_SIGMA
traverseErrValueElim g (ValueMatch p x y b) = ValueMatch
<$> traverseErrValueElim g p
<*> pure x
<*> pure y
<*> transverseScope (traverseErrValueIntro g) b
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
traverseErrValueElim g (ValueJ v3 a p r u v w) = ValueJ v3
<$> traverseErrValueIntro g a
<*> transverseScope (traverseErrValueIntro g) p
<*> traverseErrValueIntro g r
<*> traverseErrValueIntro g u
<*> traverseErrValueIntro g v
<*> traverseErrValueElim g w
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
traverseErrValueElim g (ValueAbsurd a x) = ValueAbsurd
<$> traverseErrValueIntro g a
<*> traverseErrValueElim g x
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
traverseErrValueElim g (ValueBoolElim x p t f n) = ValueBoolElim x
<$> transverseScope (traverseErrValueIntro g) p
<*> traverseErrValueIntro g t
<*> traverseErrValueIntro g f
<*> traverseErrValueElim g n
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
traverseErrValueElim g (ValueAnd x y) = ValueAnd
<$> traverseErrValueElim g x
<*> traverseErrValueElim g y
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
traverseErrValueElim f (ValueNatElim x a z s n) = ValueNatElim x
<$> transverseScope (traverseErrValueIntro f) a
<*> traverseErrValueIntro f z
<*> traverseErrValueIntro f s
<*> traverseErrValueElim f n
#ifdef LANGUAGE_PTS_HAS_NAT_PRIM
traverseErrValueElim g (ValuePlus x y) = ValuePlus
<$> traverseErrValueElim g x
<*> traverseErrValueElim g y
traverseErrValueElim g (ValueTimes x y) = ValueTimes
<$> traverseErrValueElim g x
<*> traverseErrValueElim g y
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
traverseErrValueElim f (ValueQuarkElim x p ls l) = ValueQuarkElim x
<$> transverseScope (traverseErrValueIntro f) p
<*> traverse (traverseErrValueIntro f) ls
<*> traverseErrValueElim f l
#endif
#ifdef LANGUAGE_PTS_HAS_FIX
traverseErrValueElim f (ValueFix g) = ValueFix <$> traverseErrValueElim f g
#endif
errorlessValueIntro :: MonadErr m => ValueIntro Err s a -> m (ValueIntro err' s a)
errorlessValueIntro = traverseErrValueIntro throwErr
errorlessValueElim :: MonadErr m => ValueElim Err s a -> m (ValueElim err' s a)
errorlessValueElim = traverseErrValueElim throwErr
errorlessValueIntro' :: MonadErr m => ValueIntro Err s a -> m (ValueIntro Void s a)
errorlessValueElim' :: MonadErr m => ValueElim Err s a -> m (ValueElim Void s a)
errorlessValueIntro' = errorlessValueIntro
errorlessValueElim' = errorlessValueElim
instance (Show s, Show err) => Show1 (ValueIntro err s) where
liftShowsPrec sp sl d (ValueLam x y z) = showsTernaryWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueLam" d x y z
liftShowsPrec sp sl d (ValueCoerce x) = showsUnaryWith
(liftShowsPrec sp sl)
"ValueCoerce"
d x
liftShowsPrec _ _ d (ValueSort x) = showsUnaryWith
showsPrec
"ValueSort" d x
liftShowsPrec sp sl d (ValuePi x y z) = showsTernaryWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValuePi" d x y z
liftShowsPrec _ _ d (ValueErr err) = showsUnaryWith
showsPrec
"ValueErr" d err
#ifdef LANGUAGE_PTS_HAS_SIGMA
liftShowsPrec sp sl d (ValueSigma x y z) = showsTernaryWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueSigma" d x y z
liftShowsPrec sp sl d (ValuePair x y) = showsBinaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValuePair" d x y
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
liftShowsPrec sp sl d (ValueEquality x y z) = showsTernaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueEquality" d x y z
liftShowsPrec _ _ _ ValueRefl = showString "ValueRefl"
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
liftShowsPrec _ _ _ ValueUnit = showString "ValueBool"
liftShowsPrec _ _ _ ValueI = showString "ValueI"
liftShowsPrec _ _ _ ValueEmpty = showString "ValueEmpty"
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
liftShowsPrec _ _ _ ValueBool = showString "ValueBool"
liftShowsPrec _ _ _ ValueTrue = showString "ValueTrue"
liftShowsPrec _ _ _ ValueFalse = showString "ValueFalse"
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
liftShowsPrec _ _ _ ValueNat = showString "ValueNat"
liftShowsPrec _ _ _ ValueNatZ = showString "ValueNatZ"
liftShowsPrec sp sl d (ValueNatS x) = showsUnaryWith
(liftShowsPrec sp sl)
"ValueNatS" d x
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
liftShowsPrec _ _ d (ValueHadron ls) = showsUnaryWith
showsPrec
"ValueHadron" d (Set.toList ls)
liftShowsPrec _ _ d (ValueQuark l) = showsUnaryWith
showsPrec
"ValueQuark" d l
#endif
instance (Show s, Show err) => Show1 (ValueElim err s) where
liftShowsPrec sp _ d (ValueVar x) =
showsUnaryWith sp "ValueVar" d x
liftShowsPrec sp sl d (ValueApp x y) =
showsBinaryWith (liftShowsPrec sp sl) (liftShowsPrec sp sl) "ValueApp" d x y
#ifdef LANGUAGE_PTS_HAS_SIGMA
liftShowsPrec sp sl d (ValueMatch x y z w) = showsQuadWith
(liftShowsPrec sp sl)
showsPrec
showsPrec
(liftShowsPrec sp sl)
"ValueMatch" d x y z w
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
liftShowsPrec sp sl d (ValueJ v3 a p r u v w) = showParen (d >= 10)
$ showString "ValueJ"
. showChar ' ' . showsPrec 11 v3
. showChar ' ' . liftShowsPrec sp sl 11 a
. showChar ' ' . liftShowsPrec sp sl 11 p
. showChar ' ' . liftShowsPrec sp sl 11 r
. showChar ' ' . liftShowsPrec sp sl 11 u
. showChar ' ' . liftShowsPrec sp sl 11 v
. showChar ' ' . liftShowsPrec sp sl 11 w
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
liftShowsPrec sp sl d (ValueAbsurd x y) = showsBinaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueAbsurd" d x y
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
liftShowsPrec sp sl d (ValueBoolElim x y z w u) = showsQuintWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueBoolElim" d x y z w u
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
liftShowsPrec sp sl d (ValueAnd x y) = showsBinaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueAnd" d x y
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
liftShowsPrec sp sl d (ValueNatElim x y z w u) = showsQuintWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueNatElim" d x y z w u
#ifdef LANGUAGE_PTS_HAS_NAT_PRIM
liftShowsPrec sp sl d (ValuePlus x y) = showsBinaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValuePlus" d x y
liftShowsPrec sp sl d (ValueTimes x y) = showsBinaryWith
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueTimes" d x y
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
liftShowsPrec sp sl d (ValueQuarkElim x p ls l) = showsQuadWith
showsPrec
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
(liftShowsPrec sp sl)
"ValueQuarkElim" d x p (P $ Map.toList ls) l
#endif
#ifdef LANGUAGE_PTS_HAS_FIX
liftShowsPrec sp sl d (ValueFix x) = showsUnaryWith
(liftShowsPrec sp sl)
"ValueFix" d x
#endif
instance (Show a, Show err, Show s) => Show (ValueIntro err s a) where showsPrec = showsPrec1
instance (Show a, Show err, Show s) => Show (ValueElim err s a) where showsPrec = showsPrec1
instance Eq s => Eq1 (ValueIntro err s) where
liftEq _ (ValueSort s) (ValueSort s') = s == s'
liftEq eq (ValueCoerce x) (ValueCoerce x') = liftEq eq x x'
liftEq eq (ValueLam _ t x) (ValueLam _ t' x') =
liftEq eq x x' && liftEq eq t t'
liftEq eq (ValuePi _ a b) (ValuePi _ a' b') =
liftEq eq a a' && liftEq eq b b'
liftEq _ (ValueErr _) (ValueErr _) = False
#ifdef LANGUAGE_PTS_HAS_SIGMA
liftEq eq (ValueSigma _x a b) (ValueSigma _x' a' b') =
liftEq eq a a' &&
liftEq eq b b'
liftEq eq (ValuePair a b) (ValuePair a' b') =
liftEq eq a a' &&
liftEq eq b b'
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
liftEq eq (ValueEquality a x y) (ValueEquality a' x' y') =
liftEq eq a a' &&
liftEq eq x x' &&
liftEq eq y y'
liftEq _eq ValueRefl ValueRefl = True
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
liftEq _ ValueUnit ValueUnit = True
liftEq _ ValueI ValueI = True
liftEq _ ValueEmpty ValueEmpty = True
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
liftEq _ ValueBool ValueBool = True
liftEq _ ValueTrue ValueTrue = True
liftEq _ ValueFalse ValueFalse = True
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
liftEq _ ValueNat ValueNat = True
liftEq _ ValueNatZ ValueNatZ = True
liftEq eq (ValueNatS n) (ValueNatS n') = liftEq eq n n'
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
liftEq _ (ValueHadron ls) (ValueHadron ls') = ls == ls'
liftEq _ (ValueQuark l) (ValueQuark l') = l == l'
#endif
liftEq _eq _ _ = False
instance Eq s => Eq1 (ValueElim err s) where
liftEq eq (ValueVar a) (ValueVar a') = eq a a'
liftEq eq (ValueApp f x) (ValueApp f' x') = liftEq eq f f' && liftEq eq x x'
#ifdef LANGUAGE_PTS_HAS_SIGMA
liftEq eq (ValueMatch p _ _ b) (ValueMatch p' _ _ b') =
liftEq eq p p' &&
liftEq eq b b'
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
liftEq eq (ValueJ _ a p r x y z) (ValueJ _ a' p' r' x' y' z') =
liftEq eq a a' &&
liftEq eq p p' &&
liftEq eq r r' &&
liftEq eq x x' &&
liftEq eq y y' &&
liftEq eq z z'
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
liftEq eq (ValueAbsurd a x) (ValueAbsurd a' x') =
liftEq eq a a' &&
liftEq eq x x'
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
liftEq eq (ValueBoolElim _ p t f b) (ValueBoolElim _ p' t' f' b') =
liftEq eq p p' &&
liftEq eq t t' &&
liftEq eq f f' &&
liftEq eq b b'
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
liftEq eq (ValueAnd x y) (ValueAnd x' y') =
liftEq eq x x' &&
liftEq eq y y'
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
liftEq eq (ValueNatElim _ a z s n) (ValueNatElim _ a' z' s' n') =
liftEq eq a a' &&
liftEq eq z z' &&
liftEq eq s s' &&
liftEq eq n n'
#ifdef LANGUAGE_PTS_HAS_NAT_PRIM
liftEq eq (ValuePlus x y) (ValuePlus x' y') =
liftEq eq x x' &&
liftEq eq y y'
liftEq eq (ValueTimes x y) (ValueTimes x' y') =
liftEq eq x x' &&
liftEq eq y y'
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
liftEq eq (ValueQuarkElim _ p ls l) (ValueQuarkElim _ p' ls' l') =
liftEq eq p p' &&
liftEq (liftEq eq) ls ls' &&
liftEq eq l l'
#endif
liftEq _eq _ _ = False
instance (Eq a, Eq s) => Eq (ValueIntro err s a) where (==) = eq1
instance (Eq a, Eq s) => Eq (ValueElim err s a) where (==) = eq1
instance (Specification s, PrettyPrec err) => PrettyPrec1 (ValueIntro err s) where
liftPpp p d t = traverse (p PrecApp) t >>= pppIntro d
pppIntro :: forall err s. (Specification s, PrettyPrec err) => Prec -> ValueIntro err s Doc -> PrettyM Doc
pppIntro d (ValueCoerce x) = pppElim d x
pppIntro d (ValueSort s) = ppp d s
pppIntro d (ValueErr e) = ppp d e
pppIntro d v@ValueLam {} = uncurry (pppLambda d) =<< pppPeelLam v
pppIntro d v@ValuePi {} = uncurry (pppPi d) =<< pppPeelPi v
#ifdef LANGUAGE_PTS_HAS_EQUALITY
pppIntro d (ValueEquality a x y) = pppApplication d
"Eq"
[ pppIntro PrecApp a
, pppIntro PrecApp x
, pppIntro PrecApp y
]
pppIntro _ ValueRefl = "refl"
#endif
#ifdef LANGUAGE_PTS_HAS_SIGMA
pppIntro d v@ValueSigma {} = uncurry (pppPi d) =<< pppPeelPi v
pppIntro d (ValuePair a b) = pppApplication d
"pair"
[ pppIntro PrecApp a
, pppIntro PrecApp b
]
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
pppIntro _ ValueUnit = pppChar '⊤'
pppIntro _ ValueI = pppChar 'I'
pppIntro _ ValueEmpty = pppChar '⊥'
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
pppIntro _ ValueBool = pppChar '𝔹'
pppIntro _ ValueTrue = pppText "true"
pppIntro _ ValueFalse = pppText "false"
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
pppIntro _ ValueNat = pppChar 'ℕ'
pppIntro _ ValueNatZ = pppChar '0'
pppIntro d (ValueNatS n)
| Just n' <- valueIntroToNatural n = pppIntegral $ succ n'
| otherwise = pppApplication d
(pppChar 'S')
[pppIntro PrecApp n]
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
pppIntro _ (ValueHadron ls) = pppHadron ls
pppIntro _ (ValueQuark l) = pppQuark l
#endif
pppPeelLam :: (Specification s, PrettyPrec err) => ValueIntro err s Doc -> PrettyM ([Doc], PrettyM Doc)
pppPeelLam (ValueLam n t b) = pppScopedIrrSym n $ \nDoc -> do
~(xs, ys) <- pppPeelLam (instantiate1return nDoc b)
ntDoc <- pppAnnotation PrecAnn (return nDoc) (pppIntro PrecAnn t)
return (ntDoc : xs, ys)
pppPeelLam v = return ([], pppIntro PrecLambda v)
pppPeelPi :: (PrettyPrec err, Specification s) => ValueIntro err s Doc -> PrettyM ([PPPi], PrettyM Doc)
pppPeelPi (ValuePi n a b)
| Just b' <- unusedScope b = do
~(xs, ys) <- pppPeelPi b'
return (PPArrow (pppIntro PrecPi a) : xs, ys)
| ValueSort a' <- a, a' == typeSort =
pppScopedIrrSym n $ \nDoc -> do
~(xs, ys) <- pppPeelPi (instantiate1return nDoc b)
return (PPForall nDoc : xs, ys)
| otherwise =
pppScopedIrrSym n $ \nDoc -> do
~(xs, ys) <- pppPeelPi (instantiate1return nDoc b)
return (PPPi nDoc (pppIntro PrecPi a) : xs, ys)
#ifdef LANGUAGE_PTS_HAS_SIGMA
pppPeelPi (ValueSigma n a b)
| ValueSort a' <- a, a' == typeSort =
pppScopedIrrSym n $ \nDoc -> do
~(xs, ys) <- pppPeelPi (instantiate1return nDoc b)
return (PPExists nDoc : xs, ys)
| otherwise =
pppScopedIrrSym n $ \nDoc -> do
~(xs, ys) <- pppPeelPi (instantiate1return nDoc b)
return (PPSigma nDoc (pppIntro PrecPi a) : xs, ys)
#endif
pppPeelPi v = return ([], pppIntro PrecPi v)
instance (Specification s, PrettyPrec err) => PrettyPrec1 (ValueElim err s) where
liftPpp p d t = traverse (p PrecApp) t >>= pppElim d
pppElim :: (Specification s, PrettyPrec err) => Prec -> ValueElim err s Doc -> PrettyM Doc
pppElim _ (ValueVar a) = return a
pppElim d t@ValueApp {} = uncurry (pppApplication d) (pppPeelApplication t)
#ifdef LANGUAGE_PTS_HAS_SIGMA
pppElim d (ValueMatch p x y b) = pppApplication d
(pppText "match")
[ pppElim PrecApp p
, pppScopedIrrSym x $ \xDoc -> pppScopedIrrSym y $ \yDoc ->
pppLambda PrecApp [xDoc, yDoc] $ pppIntro PrecLambda $ instantiate2return xDoc yDoc b
]
#endif
#ifdef LANGUAGE_PTS_HAS_EQUALITY
pppElim d (ValueJ (V3 x y z) a p r u v w) = pppApplication d
(pppText "J")
[ pppIntro PrecApp a
, pppScopedIrrSym x $ \xDoc ->
pppScopedIrrSym y $ \yDoc ->
pppScopedIrrSym z $ \zDoc ->
pppLambda PrecApp [xDoc,yDoc,zDoc] $ pppIntro PrecLambda $ instantiate3return xDoc yDoc zDoc p
, pppIntro PrecApp r
, pppIntro PrecApp u
, pppIntro PrecApp v
, pppElim PrecApp w
]
#endif
#ifdef LANGUAGE_PTS_HAS_PROP
pppElim d (ValueAbsurd a x) = pppApplication d
(pppText "absurd-as") [ pppIntro PrecApp a, pppElim PrecApp x ]
#endif
#ifdef LANGUAGE_PTS_HAS_BOOL
pppElim d (ValueBoolElim x p t f b) = pppApplication d
(pppText "𝔹-elim")
[ pppScopedIrrSym x $ \xDoc -> pppLambda PrecApp [xDoc] $ pppIntro PrecLambda $ instantiate1return xDoc p
, pppIntro PrecApp t
, pppIntro PrecApp f
, pppElim PrecApp b
]
#ifdef LANGUAGE_PTS_HAS_BOOL_PRIM
pppElim d (ValueAnd x y) = pppApplication d
(pppText "𝔹-and")
[ pppElim PrecApp x
, pppElim PrecApp y
]
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_NAT
pppElim d (ValueNatElim x a z s n) = pppApplication d
(pppText "ℕ-elim")
[ pppScopedIrrSym x $ \xDoc -> pppLambda PrecApp [xDoc] $ pppIntro PrecLambda $ instantiate1return xDoc a
, pppIntro PrecApp z
, pppIntro PrecApp s
, pppElim PrecApp n
]
#ifdef LANGUAGE_PTS_HAS_NAT_PRIM
pppElim d (ValuePlus x y) = pppApplication d
(pppText "ℕ-plus")
[ pppElim PrecApp x
, pppElim PrecApp y
]
pppElim d (ValueTimes x y) = pppApplication d
(pppText "ℕ-times")
[ pppElim PrecApp x
, pppElim PrecApp y
]
#endif
#endif
#ifdef LANGUAGE_PTS_HAS_QUARKS
pppElim d (ValueQuarkElim x p qs q) = pppQuarkElim d x
(\xDoc -> pppIntro PrecLambda $ instantiate1return xDoc p)
(fmap (pppIntro PrecApp) qs)
(pppElim PrecApp q)
#endif
#ifdef LANGUAGE_PTS_HAS_FIX
pppElim d (ValueFix f) = pppApplication d
(pppText "fix") [pppIntro PrecApp f]
#endif
pppPeelApplication :: (Specification s, PrettyPrec err) => ValueElim err s Doc -> (PrettyM Doc, [PrettyM Doc])
pppPeelApplication (ValueApp f x) =
let ~(f', xs) = pppPeelApplication f
in (f', xs ++ [pppIntro PrecApp x])
pppPeelApplication v = (pppElim PrecApp v, [])
instance (Specification s, PrettyPrec err, PrettyPrec a) => PrettyPrec (ValueIntro err s a) where ppp = ppp1
instance (Specification s, PrettyPrec err, PrettyPrec a) => PrettyPrec (ValueElim err s a) where ppp = ppp1
#ifdef LANGUAGE_PTS_HAS_NAT
valueIntroToNatural :: ValueIntro err s a -> Maybe Natural
valueIntroToNatural ValueNatZ = Just 0
valueIntroToNatural (ValueNatS n) = succ <$> valueIntroToNatural n
valueIntroToNatural _ = Nothing
#endif