1
1
mirror of https://github.com/anoma/juvix.git synced 2024-09-20 21:17:13 +03:00
juvix/lab/Syntax/Core.hs
2022-03-25 00:48:43 +01:00

201 lines
5.4 KiB
Haskell

{-# OPTIONS_GHC -fno-warn-missing-export-lists #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}
module MiniJuvix.Syntax.Core where
--------------------------------------------------------------------------------
-- import Algebra.Graph.Label (Semiring (..))
import MiniJuvix.Prelude hiding (Local)
import Numeric.Natural (Natural)
--------------------------------------------------------------------------------
-- Quantity (a.k.a. Usage)
--------------------------------------------------------------------------------
data Quantity
= Zero
| One
| Many
instance Eq Quantity where
Zero == Zero = True
One == One = True
Many == Many = True
_ == _ = False
compareQuantity :: Quantity -> Quantity -> Ordering
compareQuantity Zero Zero = EQ
compareQuantity Zero _ = LT
compareQuantity _ Zero = GT
compareQuantity One One = EQ
compareQuantity One _ = LT
compareQuantity _ One = GT
compareQuantity Many Many = EQ
instance Ord Quantity where
compare = compareQuantity
x < y = compareQuantity x y == LT
x > y = compareQuantity x y == GT
x <= y = compareQuantity x y /= GT
x >= y = compareQuantity x y /= LT
max x y = if compareQuantity x y == LT then y else x
min x y = if compareQuantity x y == GT then y else x
instance Semigroup Quantity where
Zero <> _ = Zero
One <> m = m
Many <> Zero = Zero
Many <> One = Many
Many <> Many = Many
instance Monoid Quantity where
mempty = Zero
instance Semiring Quantity where
one = One
(<.>) Zero _ = Zero
(<.>) One m = m
(<.>) Many Zero = Zero
(<.>) Many One = Many
(<.>) Many Many = Many
data Relevance
= Relevant
| Irrelevant
deriving stock instance Eq Relevance
deriving stock instance Ord Relevance
relevancy :: Quantity -> Relevance
relevancy Zero = Irrelevant
relevancy _ = Relevant
type Index = Natural
type BindingName = String
data Name
= Global String
| Local BindingName Index
instance Eq Name where
Global x == Global y = x == y
Local x1 y1 == Local x2 y2 = x1 == x2 && y1 == y2
_ == _ = False
data Variable
= Bound Index
| Free Name
instance Eq Variable where
Bound x == Bound y = x == y
Free x == Free y = x == y
_ == _ = False
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Type-checkable terms.
--------------------------------------------------------------------------------
data CheckableTerm
= UniverseType
| PiType Quantity BindingName CheckableTerm CheckableTerm
| Lam BindingName CheckableTerm
| TensorType Quantity BindingName CheckableTerm CheckableTerm
| TensorIntro CheckableTerm CheckableTerm
| UnitType
| Unit
| SumType CheckableTerm CheckableTerm
| Inl CheckableTerm
| Inr CheckableTerm
| Inferred InferableTerm
data InferableTerm
= Var Variable
| Ann CheckableTerm CheckableTerm
| App InferableTerm CheckableTerm
| TensorTypeElim
Quantity
BindingName
BindingName
BindingName
InferableTerm
CheckableTerm
CheckableTerm
| SumTypeElim
Quantity
BindingName
InferableTerm
BindingName
CheckableTerm
BindingName
CheckableTerm
CheckableTerm
--------------------------------------------------------------------------------
-- Type-inferable terms (a.k.a terms that synthesise)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Term Equality
--------------------------------------------------------------------------------
checkEq :: CheckableTerm -> CheckableTerm -> Bool
checkEq UniverseType UniverseType = True
checkEq (PiType q _ a b) (PiType q _ a b) =
q == q && checkEq a a && checkEq b b
checkEq (TensorType q _ a b) (TensorType q _ a b) =
q == q && checkEq a a && checkEq b b
checkEq (TensorIntro x y) (TensorIntro x y) =
checkEq x x && checkEq y y
checkEq UnitType UnitType = True
checkEq Unit Unit = True
checkEq (SumType x y) (SumType x y) =
checkEq x x && checkEq y y
checkEq (Inl x) (Inl y) = checkEq x y
checkEq (Inr x) (Inr y) = checkEq x y
checkEq (Inferred x) (Inferred y) = inferEq x y
checkEq _ _ = False
inferEq :: InferableTerm -> InferableTerm -> Bool
inferEq (Var x) (Var y) = x == y
inferEq (Ann x y) (Ann x y) = checkEq x x && checkEq y y
inferEq (App x y) (App x y) = inferEq x x && checkEq y y
inferEq
(TensorTypeElim q _ _ _ a b c)
(TensorTypeElim q _ _ _ a b c) =
q == q && inferEq a a && checkEq b b && checkEq c c
inferEq
(SumTypeElim q _ x _ a _ b c)
(SumTypeElim q _ x _ a _ b c) =
q == q
&& inferEq x x
&& checkEq a a
&& checkEq b b
&& checkEq c c
inferEq _ _ = False
instance Eq CheckableTerm where
(==) = checkEq
instance Eq InferableTerm where
(==) = inferEq
data Term
= Checkable CheckableTerm
| Inferable InferableTerm
termEq :: Term -> Term -> Bool
termEq (Checkable (Inferred x)) (Inferable y) = x == y
termEq (Checkable x) (Checkable y) = x == y
termEq (Inferable x) (Checkable (Inferred y)) = x == y
termEq (Inferable x) (Inferable y) = x == y
termEq _ _ = False
instance Eq Term where
(==) = termEq