hoq-0.2: src/Semantics/Value.hs
module Semantics.Value
( Value(..), Eval(..)
, Level(..), level
, Con(..), ICon(..)
, ID, Sort(..)
, POrd(..), DOrd(..), lessOrEqual
) where
import Syntax.Term
data Value t
= Lam
| Pi Sort Sort
| Con (Con t)
| CCon
| FunCall ID (Eval t)
| Universe Sort
| DataType ID Int
| Interval
| Path Sort
| At
| Coe
| Iso
| Squeeze
| Case [Term (String, Con t) String]
data Con t = DCon Int Int (Eval t) | PCon | ICon ICon
data ICon = ILeft | IRight deriving Eq
data Eval t = SynEval t | PatEval [([Term (String, Con t) String], t)]
type ID = Int
data Level = Level Int | NoLevel
data Sort = TypeK Level | Set Level | Prop | Contr deriving Eq
instance Eq (Value t) where
Lam == Lam = True
Pi{} == Pi{} = True
Con c == Con c' = c == c'
CCon == CCon = True
FunCall n _ == FunCall n' _ = n == n'
Universe k == Universe k' = k == k'
DataType n _ == DataType n' _ = n == n'
Interval == Interval = True
Path{} == Path{} = True
At == At = True
Coe == Coe = True
Iso == Iso = True
Squeeze == Squeeze = True
Case pats == Case pats' = and (zipWith cmpPats pats pats')
where
cmpPats :: Term (s, Con t) u -> Term (s', Con t) u' -> Bool
cmpPats Var{} Var{} = True
cmpPats (Apply (_,c) pats) (Apply (_,c') pats') = c == c' && and (zipWith cmpPats pats pats')
cmpPats _ _ = False
_ == _ = False
instance Eq (Con t) where
DCon i _ _ == DCon i' _ _ = i == i'
ICon c == ICon c' = c == c'
PCon == PCon = True
_ == _ = False
instance Eq Level where
l1 == l2 = level l1 == level l2
instance Ord Level where
compare l1 l2 = compare (level l1) (level l2)
instance Show Level where
show NoLevel = ""
show (Level l) = show l
instance Read Level where
readsPrec _ s = case reads s of
[] -> [(NoLevel, s)]
is -> map (\(i,r) -> (Level i, r)) is
instance Enum Level where
toEnum 0 = NoLevel
toEnum n = Level n
fromEnum = level
level :: Level -> Int
level (Level l) = l
level NoLevel = 0
class POrd a where
pcompare :: a -> a -> Maybe Ordering
class POrd a => DOrd a where
dmax :: a -> a -> a
dmaximum :: [a] -> a
dmaximum [] = error "dmaximum: empty list"
dmaximum xs = foldl1 dmax xs
lessOrEqual :: POrd a => a -> a -> Bool
lessOrEqual t t' = case pcompare t t' of
Just r | r == EQ || r == LT -> True
_ -> False
instance POrd Sort where
pcompare Contr Contr = Just EQ
pcompare Contr _ = Just LT
pcompare _ Contr = Just GT
pcompare Prop Prop = Just EQ
pcompare Prop _ = Just LT
pcompare _ Prop = Just GT
pcompare (Set a) (Set b) = Just (compare a b)
pcompare (TypeK a) (TypeK b) = Just (compare a b)
pcompare (Set a) (TypeK b) = if a <= b then Just LT else Nothing
pcompare (TypeK a) (Set b) = if a >= b then Just GT else Nothing
instance DOrd Sort where
dmax a b = case pcompare a b of
Just LT -> b
Just _ -> a
Nothing -> case (a, b) of
(Set l1, TypeK l2) -> TypeK (max l1 l2)
(TypeK l1, Set l2) -> TypeK (max l1 l2)
_ -> a
dmaximum [] = TypeK NoLevel
dmaximum ks = foldl1 dmax ks
instance Show Sort where
show Contr = "Contr"
show Prop = "Prop"
show (Set a) = "Set" ++ show a
show (TypeK a) = "Type" ++ show a
instance Read Sort where
readsPrec _ ('C':'o':'n':'t':'r':s) = [(Contr,s)]
readsPrec _ ('P':'r':'o':'p':s) = [(Prop,s)]
readsPrec _ ('S':'e':'t':s) = map (\(l,s) -> (Set l, s)) (reads s)
readsPrec _ ('T':'y':'p':'e':s) = map (\(l,s) -> (TypeK l, s)) (reads s)
readsPrec _ _ = []
instance Enum Sort where
succ Contr = Prop
succ Prop = Set NoLevel
succ (Set l) = TypeK (succ l)
succ (TypeK l) = TypeK (succ l)
toEnum n = TypeK (toEnum n)
fromEnum Contr = -2
fromEnum Prop = -1
fromEnum (Set l) = fromEnum l
fromEnum (TypeK l) = fromEnum l