-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDerivation.hs
More file actions
131 lines (114 loc) · 3.58 KB
/
Copy pathDerivation.hs
File metadata and controls
131 lines (114 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{-# OPTIONS_GHC -Wno-unused-imports #-}
module LambdaBuffers.Compiler.KindCheck.Derivation (
Derivation (Axiom, Abstraction, Application, Implication),
QClassName (QClassName),
d'type,
d'kind,
Judgement (Judgement),
j'type,
j'kind,
j'ctx,
Context (Context),
context,
addContext,
getAllContext,
classContext,
) where
import Control.Lens (Lens', lens, makeLenses, (&), (.~), (^.))
import Control.Lens.Operators ((%~))
import Data.Map qualified as M
import LambdaBuffers.Compiler.KindCheck.Kind (Kind)
import LambdaBuffers.Compiler.KindCheck.Type (Type, Variable (QualifiedTyClassRef))
import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess)
import Prettyprinter (
Doc,
Pretty (pretty),
braces,
comma,
encloseSep,
hang,
hsep,
lbracket,
line,
punctuate,
rbracket,
space,
(<+>),
)
-- | Qualified Class Name.
data QClassName = QClassName
data Context = Context
{ _context :: M.Map (InfoLess Variable) Kind
, _addContext :: M.Map (InfoLess Variable) Kind
, _classContext :: M.Map (InfoLess Variable) Kind
}
deriving stock (Show, Eq)
makeLenses ''Context
instance Pretty Context where
pretty c = case M.toList (c ^. addContext) of
[] -> "Γ"
ctx -> "Γ" <+> "∪" <+> braces (setPretty ctx)
where
setPretty :: [(InfoLess Variable, Kind)] -> Doc ann
setPretty = hsep . punctuate comma . fmap (\(v, t) -> pretty v <> ":" <+> pretty t)
instance Semigroup Context where
c1 <> c2 =
c1
& context %~ (<> c2 ^. context)
& addContext %~ (<> c2 ^. addContext)
& classContext %~ (<> c2 ^. classContext)
instance Monoid Context where
mempty = Context mempty mempty mempty
-- | Utility to unify the two T.
getAllContext :: Context -> M.Map (InfoLess Variable) Kind
getAllContext c = c ^. context <> c ^. addContext <> c ^. classContext
data Judgement = Judgement
{ _j'ctx :: Context
, _j'type :: Type
, _j'kind :: Kind
}
deriving stock (Show, Eq)
makeLenses ''Judgement
instance Pretty Judgement where
pretty j = pretty (j ^. j'ctx) <+> "⊢" <+> pretty (j ^. j'type) <+> ":" <+> pretty (j ^. j'kind)
data Derivation
= Axiom Judgement
| Abstraction Judgement Derivation
| Application Judgement Derivation Derivation
| Implication Judgement Derivation
deriving stock (Show, Eq)
instance Pretty Derivation where
pretty x = case x of
Axiom j -> hang 2 $ pretty j
Abstraction j d -> dNest j [d]
Application j d1 d2 -> dNest j [d1, d2]
Implication j d -> dNest j [d]
where
dNest :: forall a b c. (Pretty a, Pretty b) => a -> [b] -> Doc c
dNest j ds = pretty j <> line <> hang 2 (encloseSep (lbracket <> space) rbracket (space <> "∧" <> space) (pretty <$> ds))
d'type :: Lens' Derivation Type
d'type = lens from to
where
from = \case
Axiom j -> j ^. j'type
Abstraction j _ -> j ^. j'type
Application j _ _ -> j ^. j'type
Implication j _ -> j ^. j'type
to drv t = case drv of
Axiom j -> Axiom $ j & j'type .~ t
Abstraction j d -> Abstraction (j & j'type .~ t) d
Application j d1 d2 -> Application (j & j'type .~ t) d1 d2
Implication j d -> Implication (j & j'type .~ t) d
d'kind :: Lens' Derivation Kind
d'kind = lens from to
where
from = \case
Axiom j -> j ^. j'kind
Abstraction j _ -> j ^. j'kind
Application j _ _ -> j ^. j'kind
Implication j _ -> j ^. j'kind
to der t = case der of
Axiom j -> Axiom $ j & j'kind .~ t
Abstraction j d -> Abstraction (j & j'kind .~ t) d
Application j d1 d2 -> Application (j & j'kind .~ t) d1 d2
Implication j d -> Abstraction (j & j'kind .~ t) d