summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Brown <greg.brown01@ed.ac.uk>2023-01-05 17:06:33 +0000
committerGreg Brown <greg.brown01@ed.ac.uk>2023-01-05 17:06:33 +0000
commit06bd13433cb5e7edcff551454107c9d4e4d88f8f (patch)
treea2eae19d92df1564290f3ff53c68587d0d696384
parent3950a84c00f54ab39f2a209c368cc02460eeebd7 (diff)
Add more program structure to normal forms.
-rw-r--r--src/Obs/Abstract.idr46
-rw-r--r--src/Obs/Logging.idr10
-rw-r--r--src/Obs/NormalForm.idr267
-rw-r--r--src/Obs/NormalForm/Normalise.idr714
-rw-r--r--src/Obs/Parser.idr185
-rw-r--r--src/Obs/Pretty.idr17
-rw-r--r--src/Obs/Syntax.idr44
-rw-r--r--src/Obs/Term.idr45
-rw-r--r--src/Obs/Typing.idr136
-rw-r--r--src/Obs/Typing/Context.idr4
-rw-r--r--src/Obs/Typing/Conversion.idr378
-rw-r--r--src/Obs/Universe.idr50
12 files changed, 1114 insertions, 782 deletions
diff --git a/src/Obs/Abstract.idr b/src/Obs/Abstract.idr
index 039f60e..4ef3f43 100644
--- a/src/Obs/Abstract.idr
+++ b/src/Obs/Abstract.idr
@@ -18,29 +18,45 @@ Context n = List (String, Fin n)
bind : Context n -> String -> Context (S n)
bind ctx str = (str, 0) :: map (mapSnd FS) ctx
-abstractSyntax : Context n -> Syntax -> Logging ann (Term n)
abstractSyntaxBounds : Context n -> WithBounds Syntax -> Logging ann (WithBounds (Term n))
+abstractDecl : Context n -> DeclForm -> Logging ann (DeclForm n)
+abstractDecl ctx (MkDecl var type) = do
+ type <- abstractSyntaxBounds ctx type
+ pure (MkDecl var type)
+
+abstractLambda : Context n -> LambdaForm -> Logging ann (LambdaForm n)
+abstractLambda ctx (MkLambda var body) = do
+ body <- abstractSyntaxBounds (bind ctx var.val) body
+ pure (MkLambda var body)
+
+abstractSyntax : Context n -> Syntax -> Logging ann (Term n)
abstractSyntax ctx (Var {var}) = do
let Just i = lookup var ctx
| Nothing => inScope "unbound variable" $ fatal var
pure (Var {var, i})
abstractSyntax ctx (Universe {s}) = pure (Universe {s})
-abstractSyntax ctx (Pi {var, domain, codomain}) = do
- domain <- abstractSyntaxBounds ctx domain
- codomain <- abstractSyntaxBounds (bind ctx var.val) codomain
- pure (Pi {var, domain, codomain})
-abstractSyntax ctx (Lambda {var, body}) = do
- body <- abstractSyntaxBounds (bind ctx var.val) body
- pure (Lambda {var, body})
+abstractSyntax ctx (Pi {domain, codomain}) = do
+ domain <- abstractDecl ctx domain
+
+ let ctx = bind ctx domain.var.val
+ codomain <- abstractSyntaxBounds ctx codomain
+
+ pure (Pi {domain, codomain})
+abstractSyntax ctx (Lambda {body}) = do
+ body <- abstractLambda ctx body
+ pure (Lambda {body})
abstractSyntax ctx (App {fun, arg}) = do
fun <- abstractSyntaxBounds ctx fun
arg <- abstractSyntaxBounds ctx arg
pure (App {fun, arg})
-abstractSyntax ctx (Sigma {var, index, element}) = do
- index <- abstractSyntaxBounds ctx index
- element <- abstractSyntaxBounds (bind ctx var.val) element
- pure (Sigma {var, index, element})
+abstractSyntax ctx (Sigma {index, element}) = do
+ index <- abstractDecl ctx index
+
+ let ctx = bind ctx index.var.val
+ element <- abstractSyntaxBounds ctx element
+
+ pure (Sigma {index, element})
abstractSyntax ctx (Pair {first, second}) = do
first <- abstractSyntaxBounds ctx first
second <- abstractSyntaxBounds ctx second
@@ -54,12 +70,12 @@ abstractSyntax ctx (Second {arg}) = do
abstractSyntax ctx Bool = pure Bool
abstractSyntax ctx True = pure True
abstractSyntax ctx False = pure False
-abstractSyntax ctx (If {var, returnType, discriminant, true, false}) = do
- returnType <- abstractSyntaxBounds (bind ctx var.val) returnType
+abstractSyntax ctx (If {returnType, discriminant, true, false}) = do
+ returnType <- abstractLambda ctx returnType
discriminant <- abstractSyntaxBounds ctx discriminant
true <- abstractSyntaxBounds ctx true
false <- abstractSyntaxBounds ctx false
- pure (If {var, returnType, discriminant, true, false})
+ pure (If {returnType, discriminant, true, false})
abstractSyntax ctx Top = pure Top
abstractSyntax ctx Point = pure Point
abstractSyntax ctx Bottom = pure Bottom
diff --git a/src/Obs/Logging.idr b/src/Obs/Logging.idr
index 5666001..07060e6 100644
--- a/src/Obs/Logging.idr
+++ b/src/Obs/Logging.idr
@@ -48,10 +48,10 @@ pretty msg =
let leader =
hsep $
[ fill 6 (pretty (show msg.lvl) <+> colon) ] ++
- [ Doc.pretty $ concat {t = List} $
- case msg.bounds of
- Nothing => []
- Just bounds =>
+ (case msg.bounds of
+ Nothing => []
+ Just bounds =>
+ [ Doc.pretty $ concat {t = List} $
[ show (1 + bounds.startLine)
, ":"
, show bounds.startCol
@@ -61,7 +61,7 @@ pretty msg =
, show bounds.endCol
, ":"
]
- ] ++
+ ]) ++
map (\s => pretty s <+> colon) msg.tags
in group $ width (group leader <+> line) (\width => group $ indent (2 - width) msg.msg)
diff --git a/src/Obs/NormalForm.idr b/src/Obs/NormalForm.idr
index d660111..0b9d2b6 100644
--- a/src/Obs/NormalForm.idr
+++ b/src/Obs/NormalForm.idr
@@ -2,6 +2,7 @@ module Obs.NormalForm
import Data.List.Elem
+import Obs.Pretty
import Obs.Substitution
import Obs.Universe
@@ -19,27 +20,31 @@ TypeNormalForm : Unsorted.Family Relevance
TypeNormalForm = NormalForm Relevant
public export
+record DeclForm (ctx : List Relevance) where
+ constructor MkDecl
+ var : Maybe String
+ type : TypeNormalForm ctx
+
+public export
data Constructor : Unsorted.Family Relevance where
Universe : (s : Universe) -> Constructor ctx
- Pi : (s, s' : Universe)
- -> (var : String)
- -> (a : TypeNormalForm ctx)
- -> (b : TypeNormalForm (relevance s :: ctx))
- -> Constructor ctx
- Lambda : (s : Universe)
- -> (var : String)
- -> NormalForm Relevant (relevance s :: ctx)
- -> Constructor ctx
- Sigma : (s, s' : Universe)
- -> (var : String)
- -> (a : TypeNormalForm ctx)
- -> (b : TypeNormalForm (relevance s :: ctx))
- -> Constructor ctx
- Pair : (s, s' : Universe)
- -> (prf : IsRelevant (max s s'))
- -> NormalForm (relevance s) ctx
- -> NormalForm (relevance s') ctx
- -> Constructor ctx
+ Pi : (domainSort, codomainSort : Universe) ->
+ (domain : DeclForm ctx) ->
+ (codomain : TypeNormalForm (relevance domainSort :: ctx)) ->
+ Constructor ctx
+ Lambda : (domainRel : Relevance) ->
+ (var : Maybe String) ->
+ (body : NormalForm Relevant (domainRel :: ctx)) ->
+ Constructor ctx
+ Sigma : (indexSort, elementSort : Universe) ->
+ (index : DeclForm ctx) ->
+ (element : TypeNormalForm (relevance indexSort :: ctx)) ->
+ Constructor ctx
+ Pair : (indexRel, elementRel : Relevance) ->
+ (prf : IsRelevant (pair indexRel elementRel)) ->
+ (first : NormalForm indexRel ctx) ->
+ (second : NormalForm elementRel ctx) ->
+ Constructor ctx
Bool : Constructor ctx
True : Constructor ctx
False : Constructor ctx
@@ -48,26 +53,27 @@ data Constructor : Unsorted.Family Relevance where
public export
data Neutral : Unsorted.Family Relevance where
- Var : (var : String)
- -> (sort : Universe)
- -> (prf : IsRelevant sort)
- -> (i : Elem Relevant ctx)
- -> Neutral ctx
- App : (r : Relevance) -> Neutral ctx -> NormalForm r ctx -> Neutral ctx
- Fst : (r : Relevance) -> Neutral ctx -> Neutral ctx
- Snd : (r : Relevance) -> Neutral ctx -> Neutral ctx
- If : Neutral ctx -> (f, g : NormalForm Relevant ctx) -> Neutral ctx
+ Var : (var : String) -> (i : Elem Relevant ctx) -> Neutral ctx
+ App : (argRel : Relevance) -> (fun : Neutral ctx) -> (arg : NormalForm argRel ctx) -> Neutral ctx
+ First : (secondRel : Relevance) -> (arg : Neutral ctx) -> Neutral ctx
+ Second : (firstRel : Relevance) -> (arg : Neutral ctx) -> Neutral ctx
+ If : (discriminant : Neutral ctx) -> (true, false : NormalForm Relevant ctx) -> Neutral ctx
Absurd : Neutral ctx
- Equal : Neutral ctx -> NormalForm Relevant ctx -> NormalForm Relevant ctx -> Neutral ctx
- EqualL : (a : Neutral ctx) -> (b : TypeNormalForm ctx) -> Neutral ctx
- EqualR : (a : Constructor ctx) -> (b : Neutral ctx) -> Neutral ctx
- EqualStuck : (a, b : Constructor ctx) -> Neutral ctx
- CastL : (a : Neutral ctx) ->
- (b : TypeNormalForm ctx) ->
- NormalForm Relevant ctx ->
+ Equal : (type : Neutral ctx) -> (left, right : NormalForm Relevant ctx) -> Neutral ctx
+ EqualL : (left : Neutral ctx) -> (right : TypeNormalForm ctx) -> Neutral ctx
+ EqualR : (left : Constructor ctx) -> (right : Neutral ctx) -> Neutral ctx
+ EqualStuck : (left, right : Constructor ctx) -> Neutral ctx
+ CastL : (oldType : Neutral ctx) ->
+ (newType : TypeNormalForm ctx) ->
+ (value : NormalForm Relevant ctx) ->
+ Neutral ctx
+ CastR : (oldType : Constructor ctx) ->
+ (newType : Neutral ctx) ->
+ (value : NormalForm Relevant ctx) ->
+ Neutral ctx
+ CastStuck : (oldType, newType : Constructor ctx) ->
+ (value : NormalForm Relevant ctx) ->
Neutral ctx
- CastR : (a : Constructor ctx) -> (b : Neutral ctx) -> NormalForm Relevant ctx -> Neutral ctx
- CastStuck : (a, b : Constructor ctx) -> NormalForm Relevant ctx -> Neutral ctx
public export
data NormalForm : Sorted.Family Relevance where
@@ -108,34 +114,19 @@ Cast Universe (NormalForm Relevant ctx) where
prettyPrec : Prec -> NormalForm b ctx -> Doc ann
+prettyPrecDecl : DeclForm ctx -> Doc ann
+prettyPrecDecl (MkDecl var type) = prettyDecl var (prettyPrec Open type)
+
prettyPrecCnstr : Prec -> Constructor ctx -> Doc ann
-prettyPrecCnstr d (Universe s) = prettyPrec d s
-prettyPrecCnstr d (Pi s s' var a b) =
- let lhs = case var of
- "" => align (prettyPrec App a)
- _ => parens (pretty var <++> colon <+> softline <+> align (prettyPrec Open a))
- in
- parenthesise (d > Open) $
- group $
- lhs <++> pretty "->" <+> line <+> align (prettyPrec Open b)
-prettyPrecCnstr d (Lambda _ var t) =
- parenthesise (d > Open) $
- group $
- backslash <+> pretty var <++>
- pretty "=>" <+> line <+>
- align (prettyPrec Open t)
-prettyPrecCnstr d (Sigma s s' var a b) =
- let lhs = case var of
- "" => align (prettyPrec App a)
- _ => parens (pretty var <++> colon <+> softline <+> align (prettyPrec Open a))
- in
- parenthesise (d > Open) $
- group $
- lhs <++> pretty "**" <+> line <+> align (prettyPrec Open b)
-prettyPrecCnstr d (Pair s s' prf t u) =
- angles $
- group $
- neutral <++> prettyPrec Open t <+> comma <+> line <+> prettyPrec Open u <++> neutral
+prettyPrecCnstr d (Universe {s}) = prettyPrec d s
+prettyPrecCnstr d (Pi {domainSort, codomainSort, domain, codomain}) =
+ prettyDeclForm d [prettyPrecDecl domain] "->" (prettyPrec Open codomain)
+prettyPrecCnstr d (Lambda {domainRel, var, body}) =
+ prettyLambda d (maybe "_" id var) (prettyPrec Open body)
+prettyPrecCnstr d (Sigma {indexSort, elementSort, index, element}) =
+ prettyDeclForm d [prettyPrecDecl index] "**" (prettyPrec Open element)
+prettyPrecCnstr d (Pair {indexRel, elementRel, prf, first, second}) =
+ prettyPair (prettyPrec Open first) (prettyPrec Open second)
prettyPrecCnstr d Bool = pretty "Bool"
prettyPrecCnstr d True = pretty "True"
prettyPrecCnstr d False = pretty "False"
@@ -143,52 +134,34 @@ prettyPrecCnstr d Top = pretty "()"
prettyPrecCnstr d Bottom = pretty "Void"
prettyPrecNtrl : Prec -> Neutral ctx -> Doc ann
-prettyPrecNtrl d (Var var sort prf i) = pretty "\{var}@\{show $ elemToNat i}"
-prettyPrecNtrl d (App _ t u) =
- parenthesise (d >= App) $
- group $
- vsep [prettyPrecNtrl Open t, prettyPrec App u]
-prettyPrecNtrl d (Fst _ t) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "fst", prettyPrecNtrl App t]
-prettyPrecNtrl d (Snd _ t) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "snd", prettyPrecNtrl App t]
-prettyPrecNtrl d (If t f g) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "if", prettyPrecNtrl App t, prettyPrec App f, prettyPrec App g]
+prettyPrecNtrl d (Var {var, i}) = pretty "\{var}@\{show $ elemToNat i}"
+prettyPrecNtrl d (App {argRel, fun, arg}) =
+ prettyApp d (prettyPrecNtrl Open fun) [prettyPrec App arg]
+prettyPrecNtrl d (First {secondRel, arg}) =
+ prettyApp d (pretty "fst") [prettyPrecNtrl App arg]
+prettyPrecNtrl d (Second {firstRel, arg}) =
+ prettyApp d (pretty "snd") [prettyPrecNtrl App arg]
+prettyPrecNtrl d (If {discriminant, true, false}) =
+ prettyApp d (pretty "if") $
+ [prettyPrecNtrl App discriminant, prettyPrec App true, prettyPrec App false]
prettyPrecNtrl d Absurd = pretty "absurd"
-prettyPrecNtrl d (Equal a t u) =
- parenthesise (d >= Equal) $
- group $
- prettyPrec Equal t <++> pretty "~" <+> line <+> prettyPrec Equal u
-prettyPrecNtrl d (EqualL a b) =
- parenthesise (d >= Equal) $
- group $
- prettyPrecNtrl Equal a <++> pretty "~" <+> line <+> prettyPrec Equal b
-prettyPrecNtrl d (EqualR a b) =
- parenthesise (d >= Equal) $
- group $
- prettyPrecCnstr Equal a <++> pretty "~" <+> line <+> prettyPrecNtrl Equal b
-prettyPrecNtrl d (EqualStuck a b) =
- parenthesise (d >= Equal) $
- group $
- prettyPrecCnstr Equal a <++> pretty "~" <+> line <+> prettyPrecCnstr Equal b
-prettyPrecNtrl d (CastL a b t) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "cast", prettyPrecNtrl App a, prettyPrec App b, prettyPrec App t]
-prettyPrecNtrl d (CastR a b t) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "cast", prettyPrecCnstr App a, prettyPrecNtrl App b, prettyPrec App t]
-prettyPrecNtrl d (CastStuck a b t) =
- parenthesise (d >= App) $
- group $
- vsep [pretty "cast", prettyPrecCnstr App a, prettyPrecCnstr App b, prettyPrec App t]
+prettyPrecNtrl d (Equal {type, left, right}) =
+ prettyEqual d (prettyPrec Equal left) (prettyPrec Equal right)
+prettyPrecNtrl d (EqualL {left, right}) =
+ prettyEqual d (prettyPrecNtrl Equal left) (prettyPrec Equal right)
+prettyPrecNtrl d (EqualR {left, right}) =
+ prettyEqual d (prettyPrecCnstr Equal left) (prettyPrecNtrl Equal right)
+prettyPrecNtrl d (EqualStuck {left, right}) =
+ prettyEqual d (prettyPrecCnstr Equal left) (prettyPrecCnstr Equal right)
+prettyPrecNtrl d (CastL {oldType, newType, value}) =
+ prettyApp d (pretty "cast") $
+ [prettyPrecNtrl App oldType, prettyPrec App newType, prettyPrec App value]
+prettyPrecNtrl d (CastR {oldType, newType, value}) =
+ prettyApp d (pretty "cast") $
+ [prettyPrecCnstr App oldType, prettyPrecNtrl App newType, prettyPrec App value]
+prettyPrecNtrl d (CastStuck {oldType, newType, value}) =
+ prettyApp d (pretty "cast") $
+ [prettyPrecCnstr App oldType, prettyPrecCnstr App newType, prettyPrec App value]
prettyPrec d (Ntrl t) = prettyPrecNtrl d t
prettyPrec d (Cnstr t) = prettyPrecCnstr d t
@@ -210,13 +183,35 @@ Pretty (NormalForm b ctx) where
rename : NormalForm ~|> Hom Elem NormalForm
+renameDecl : DeclForm ~|> Hom Elem DeclForm
+renameDecl (MkDecl var type) f = MkDecl var (rename type f)
+
renameCnstr : Constructor ~|> Hom Elem Constructor
-renameCnstr (Universe s) f = Universe s
-renameCnstr (Pi s s' var a b) f = Pi s s' var (rename a f) (rename b (lift [(_ ** ())] f))
-renameCnstr (Lambda s var t) f = Lambda s var (rename t (lift [(_ ** ())] f))
-renameCnstr (Sigma s s' var a b) f =
- Sigma s s' var (rename a f) (rename b (lift [(_ ** ())] f))
-renameCnstr (Pair s s' prf t u) f = Pair s s' prf (rename t f) (rename u f)
+renameCnstr (Universe {s}) f = Universe {s}
+renameCnstr (Pi {domainSort, codomainSort, domain, codomain}) f =
+ Pi
+ { domainSort
+ , codomainSort
+ , domain = renameDecl domain f
+ , codomain = rename codomain (lift [(_ ** ())] f)
+ }
+renameCnstr (Lambda {domainRel, var, body}) f =
+ Lambda {domainRel, var, body = rename body (lift [(_ ** ())] f)}
+renameCnstr (Sigma {indexSort, elementSort, index, element}) f =
+ Sigma
+ { indexSort
+ , elementSort
+ , index = renameDecl index f
+ , element = rename element (lift [(_ ** ())] f)
+ }
+renameCnstr (Pair {indexRel, elementRel, prf, first, second}) f =
+ Pair
+ { indexRel
+ , elementRel
+ , prf
+ , first = rename first f
+ , second = rename second f
+ }
renameCnstr Bool f = Bool
renameCnstr True f = True
renameCnstr False f = False
@@ -224,19 +219,30 @@ renameCnstr Top f = Top
renameCnstr Bottom f = Bottom
renameNtrl : Neutral ~|> Hom Elem Neutral
-renameNtrl (Var var sort prf i) f = Var var sort prf (f i)
-renameNtrl (App b t u) f = App b (renameNtrl t f) (rename u f)
-renameNtrl (Fst b t) f = Fst b (renameNtrl t f)
-renameNtrl (Snd b t) f = Snd b (renameNtrl t f)
-renameNtrl (If t u v) f = If (renameNtrl t f) (rename u f) (rename v f)
+renameNtrl (Var {var, i}) f = Var {var, i = f i}
+renameNtrl (App {argRel, fun, arg}) f = App {argRel, fun = renameNtrl fun f, arg = rename arg f}
+renameNtrl (First {secondRel, arg}) f = First {secondRel, arg = renameNtrl arg f}
+renameNtrl (Second {firstRel, arg}) f = Second {firstRel, arg = renameNtrl arg f}
+renameNtrl (If {discriminant, true, false}) f =
+ If {discriminant = renameNtrl discriminant f, true = rename true f, false = rename false f}
renameNtrl Absurd f = Absurd
-renameNtrl (Equal a t u) f = Equal (renameNtrl a f) (rename t f) (rename u f)
-renameNtrl (EqualL a b) f = EqualL (renameNtrl a f) (rename b f)
-renameNtrl (EqualR a b) f = EqualR (renameCnstr a f) (renameNtrl b f)
-renameNtrl (EqualStuck a b) f = EqualStuck (renameCnstr a f) (renameCnstr b f)
-renameNtrl (CastL a b t) f = CastL (renameNtrl a f) (rename b f) (rename t f)
-renameNtrl (CastR a b t) f = CastR (renameCnstr a f) (renameNtrl b f) (rename t f)
-renameNtrl (CastStuck a b t) f = CastStuck (renameCnstr a f) (renameCnstr b f) (rename t f)
+renameNtrl (Equal {type, left, right}) f =
+ Equal {type = renameNtrl type f, left = rename left f, right = rename right f}
+renameNtrl (EqualL {left, right}) f = EqualL {left = renameNtrl left f, right = rename right f}
+renameNtrl (EqualR {left, right}) f =
+ EqualR {left = renameCnstr left f, right = renameNtrl right f}
+renameNtrl (EqualStuck {left, right}) f =
+ EqualStuck {left = renameCnstr left f, right = renameCnstr right f}
+renameNtrl (CastL {oldType, newType, value}) f =
+ CastL {oldType = renameNtrl oldType f, newType = rename newType f, value = rename value f}
+renameNtrl (CastR {oldType, newType, value}) f =
+ CastR {oldType = renameCnstr oldType f, newType = renameNtrl newType f, value = rename value f}
+renameNtrl (CastStuck {oldType, newType, value}) f =
+ CastStuck
+ { oldType = renameCnstr oldType f
+ , newType = renameCnstr newType f
+ , value = rename value f
+ }
rename (Ntrl t) f = Ntrl $ renameNtrl t f
rename (Cnstr t) f = Cnstr $ renameCnstr t f
@@ -249,12 +255,13 @@ Unsorted.Rename Relevance Constructor where
export
Unsorted.Rename Relevance Neutral where
rename = renameNtrl
-
+
export
Sorted.Rename Relevance NormalForm where
rename = NormalForm.rename
export
-PointedRename Relevance (\r => (String, (s : Universe ** relevance s = r))) NormalForm where
+PointedRename Relevance (\r => Maybe String) NormalForm where
point {s = Irrelevant} _ _ = Irrel
- point {s = Relevant} (var, (s@(Set _) ** prf)) i = Ntrl (Var var s Set i)
+ point {s = Relevant} var i =
+ Ntrl (Var {var = maybe "" id var, i})
diff --git a/src/Obs/NormalForm/Normalise.idr b/src/Obs/NormalForm/Normalise.idr
index ed06fa2..2ea6296 100644
--- a/src/Obs/NormalForm/Normalise.idr
+++ b/src/Obs/NormalForm/Normalise.idr
@@ -25,11 +25,15 @@ LogNormalForm : Type -> Sorted.Family Relevance
LogNormalForm ann b ctx = Logging ann (NormalForm b ctx)
0
+LogDeclForm : Type -> Unsorted.Family Relevance
+LogDeclForm ann ctx = Logging ann (DeclForm ctx)
+
+0
LogNormalForm' : Type -> Sorted.Family Relevance
LogNormalForm' ann b ctx = Either (Logging ann (NormalForm b ctx)) (Elem b ctx)
-- Copied and specialised from Obs.Substitution
-lift : (ctx : List (r ** (String, (s ** relevance s = r))))
+lift : (ctx : List (r ** Maybe String))
-> Map ctx' (LogNormalForm' ann) ctx''
-> Map (map DPair.fst ctx ++ ctx') (LogNormalForm' ann) (map DPair.fst ctx ++ ctx'')
lift [] f = f
@@ -42,202 +46,467 @@ lift ((s ** y) :: ctx) f = add (LogNormalForm' ann)
subst' : NormalForm ~|> Hom (LogNormalForm' ann) (LogNormalForm ann)
export
-doApp : {domain : _} ->
- NormalForm (function domain codomain) ctx ->
- NormalForm domain ctx ->
- LogNormalForm ann codomain ctx
-doApp (Ntrl t) u = pure (Ntrl $ App _ t u)
-doApp (Cnstr (Lambda s var t)) u = inScope "doApp" $ do
- trace $ pretty {ann} "substituting" <++> pretty u <+> softline <+> pretty "for \{var} in" <++> pretty t
- let Yes Refl = decEq domain (relevance s)
+subst1 : {s' : _} -> NormalForm s ctx -> NormalForm s' (s :: ctx) -> LogNormalForm ann s' ctx
+subst1 t u = subst' u (add (LogNormalForm' ann) (Left $ pure t) Right)
+
+export
+map1 : {s' : _} ->
+ NormalForm s (s :: ctx) ->
+ NormalForm s' (s :: ctx) ->
+ LogNormalForm ann s' (s :: ctx)
+map1 t u = subst' u (add (LogNormalForm' ann) (Left $ pure t) (Right . There))
+
+export
+doApp : {domainRel : _} ->
+ (fun : NormalForm (function domainRel codomainRel) ctx) ->
+ (arg : NormalForm domainRel ctx) ->
+ LogNormalForm ann codomainRel ctx
+
+doApp (Ntrl fun) arg = pure $ Ntrl $ App {argRel = _, fun, arg}
+doApp (Cnstr (Lambda {domainRel = domainRel', var, body})) arg = do
+ let Yes Refl = decEq domainRel domainRel'
| No _ => fatal "internal relevance mismatch"
- subst' t (add (LogNormalForm' ann) (Left $ pure u) Right)
-doApp (Cnstr t) u = inScope "wrong constructor for apply" $ fatal t
-doApp Irrel u = pure Irrel
+
+ subst1 arg body
+doApp (Cnstr t) arg = inScope "wrong constructor for apply" $ fatal t
+doApp Irrel arg = pure Irrel
export
-doFst : (fst, snd : _) -> NormalForm (pair fst snd) ctx -> LogNormalForm ann fst ctx
-doFst Irrelevant snd t = pure Irrel
-doFst Relevant snd (Ntrl t) = pure (Ntrl $ Fst snd t)
-doFst Relevant snd (Cnstr (Pair (Set _) s' prf t u)) = pure t
-doFst Relevant snd (Cnstr t) = inScope "wrong constructor for fst" $ fatal t
+doFst : (firstRel, secondRel : _) ->
+ (arg : NormalForm (pair firstRel secondRel) ctx) ->
+ LogNormalForm ann firstRel ctx
+
+doFst Irrelevant secondRel arg = pure Irrel
+doFst Relevant secondRel (Ntrl arg) = pure $ Ntrl $ First {secondRel, arg}
+doFst Relevant secondRel (Cnstr (Pair {indexRel = Relevant, elementRel, prf, first, second})) =
+ pure first
+doFst Relevant secondRel (Cnstr t) = inScope "wrong constructor for fst" $ fatal t
export
-doSnd : (fst, snd : _) -> NormalForm (pair fst snd) ctx -> LogNormalForm ann snd ctx
-doSnd fst Irrelevant t = pure Irrel
-doSnd fst Relevant t =
- let t' : NormalForm Relevant ctx
- t' = rewrite sym $ pairRelevantRight fst in t
- in case t' of
- Ntrl t => pure (Ntrl $ Snd fst t)
- Cnstr (Pair _ (Set _) prf t u) => pure u
+doSnd : (firstRel, secondRel : _) ->
+ (arg : NormalForm (pair firstRel secondRel) ctx) ->
+ LogNormalForm ann secondRel ctx
+
+doSnd firstRel Irrelevant arg = pure Irrel
+doSnd firstRel Relevant arg =
+ let arg' : NormalForm Relevant ctx
+ arg' = rewrite sym $ pairRelevantRight firstRel in arg
+ in case arg' of
+ Ntrl arg => pure $ Ntrl $ Second {firstRel, arg}
+ Cnstr (Pair {indexRel, elementRel = Relevant, prf, first, second}) => pure second
Cnstr t => inScope "wrong constructor for snd" $ fatal t
export
-doIf : {r : _} ->
- NormalForm Relevant ctx ->
- NormalForm r ctx ->
- NormalForm r ctx ->
- LogNormalForm ann r ctx
-doIf {r = Irrelevant} t u v = pure Irrel
-doIf {r = Relevant} (Ntrl t) u v = pure (Ntrl $ If t u v)
-doIf {r = Relevant} (Cnstr True) u v = pure u
-doIf {r = Relevant} (Cnstr False) u v = pure v
-doIf {r = Relevant} (Cnstr t) u v = inScope "wrong constructor for case" $ fatal t
+doIf : {rel : _} ->
+ (discriminant : NormalForm Relevant ctx) ->
+ (true, false : NormalForm rel ctx) ->
+ LogNormalForm ann rel ctx
+doIf {rel = Irrelevant} discriminant true false = pure Irrel
+doIf {rel = Relevant} (Ntrl discriminant) true false = pure $ Ntrl $ If {discriminant, true, false}
+doIf {rel = Relevant} (Cnstr True) true false = pure true
+doIf {rel = Relevant} (Cnstr False) true false = pure false
+doIf {rel = Relevant} (Cnstr t) true false = inScope "wrong constructor for if" $ fatal t
export
-doAbsurd : (r : _) -> NormalForm r ctx
+doAbsurd : (rel : _) -> NormalForm rel ctx
doAbsurd Irrelevant = Irrel
doAbsurd Relevant = Ntrl Absurd
export
-doCast : (r : _) -> (a, b : TypeNormalForm ctx) -> NormalForm r ctx -> LogNormalForm ann r ctx
+doCast : (rel : _) ->
+ (oldType, newType : TypeNormalForm ctx) ->
+ (value : NormalForm rel ctx) ->
+ LogNormalForm ann rel ctx
-doCastR : (a : Constructor ctx) ->
- (b : TypeNormalForm ctx) ->
- NormalForm Relevant ctx ->
+doCastHelper : (oldType, newType : Constructor ctx) ->
+ (value : NormalForm Relevant ctx) ->
LogNormalForm ann Relevant ctx
-doCastR a (Ntrl b) t = pure (Ntrl $ CastR a b t)
-doCastR (Universe _) (Cnstr (Universe _)) t = pure t
-doCastR ty@(Pi s s'@(Set _) var a b) (Cnstr ty'@(Pi l l' _ a' b')) t =
- let y : NormalForm (relevance s) (relevance s :: ctx)
- y = point (var, (s ** Refl)) Here
+doCastHelper (Universe {s}) (Universe {s = s'}) value = pure value
+doCastHelper
+ oldType@(Pi {domainSort, codomainSort, domain, codomain})
+ newType@(Pi
+ { domainSort = domainSort'
+ , codomainSort = codomainSort'
+ , domain = domain'
+ , codomain = codomain'
+ })
+ value =
+ let y : NormalForm (relevance domainSort) (relevance domainSort :: ctx)
+ y = point domain.var Here
in do
- let Yes Refl = decEq (s, s') (l, l')
- | No _ => pure (Ntrl $ CastStuck ty ty' t)
- x <- assert_total (doCast (relevance s) (weaken [relevance s] a') (weaken [relevance s] a) y)
- b <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure x) (Right . There)))
- b' <- assert_total (subst' b' (add (LogNormalForm' ann) (Left $ pure y) (Right . There)))
- t <- assert_total (doApp (Sorted.weaken [relevance s] t) x)
- t <- assert_total (doCast Relevant b b' t)
- pure (Cnstr $ Lambda s var t)
-doCastR ty@(Sigma s@(Set k) s' var a b) (Cnstr ty'@(Sigma l l' _ a' b')) t = do
- let Yes Refl = decEq (s, s') (l, l')
- | No _ => pure (Ntrl $ CastStuck ty ty' t)
- t1 <- doFst Relevant (relevance s') t
- u1 <- assert_total (doCast Relevant a a' t)
- b <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure t1) Right))
- b' <- assert_total (subst' b' (add (LogNormalForm' ann) (Left $ pure u1) Right))
- t2 <- doSnd Relevant (relevance s') t
- u2 <- assert_total (doCast (relevance s') b b' t2)
- pure (Cnstr $ Pair (Set k) s' Set u1 u2)
-doCastR ty@(Sigma Prop s'@(Set k) var a b) (Cnstr ty'@(Sigma Prop l' _ a' b')) t = do
- let Yes Refl = decEq s' l'
- | No _ => pure (Ntrl $ CastStuck ty ty' t)
- b <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure Irrel) Right))
- b' <- assert_total (subst' b' (add (LogNormalForm' ann) (Left $ pure Irrel) Right))
- t2 <- doSnd Irrelevant Relevant t
- u2 <- assert_total (doCast Relevant b b' t2)
- pure (Cnstr $ Pair Prop (Set k) Set Irrel u2)
-doCastR Bool (Cnstr Bool) t = pure t
-doCastR a (Cnstr b) t = pure (Ntrl $ CastStuck a b t)
-
-doCast Irrelevant a b t = pure Irrel
-doCast Relevant (Ntrl a) b t = pure (Ntrl $ CastL a b t)
-doCast Relevant (Cnstr a) b t = doCastR a b t
+
+ let Yes Refl = decEq (domainSort, codomainSort) (domainSort', codomainSort')
+ | No _ => pure $ Ntrl $ CastStuck {oldType, newType, value}
+
+ let domainType = weaken [relevance domainSort] domain.type
+ let domainType' = weaken [relevance domainSort] domain'.type
+
+ x <- doCast
+ { rel = relevance domainSort
+ , oldType = assert_smaller oldType domainType'
+ , newType = assert_smaller newType domainType
+ , value = y
+ }
+
+ codomainType <- map1 x codomain
+ codomainType' <- map1 y codomain'
+
+ call <- doApp (weaken [relevance domainSort] value) x
+ body <- doCast
+ { rel = Relevant
+ , oldType = assert_smaller oldType codomainType
+ , newType = assert_smaller newType codomainType'
+ , value = call
+ }
+
+ pure $ Cnstr $ Lambda {domainRel = relevance domainSort, var = Nothing, body}
+doCastHelper
+ oldType@(Sigma {indexSort = indexSort@(Set k), elementSort, index, element})
+ newType@(Sigma
+ { indexSort = indexSort'
+ , elementSort = elementSort'
+ , index = index'
+ , element = element'
+ })
+ value = do
+ let Yes Refl = decEq (indexSort, elementSort) (indexSort', elementSort')
+ | No _ => pure $ Ntrl $ CastStuck {oldType, newType, value}
+
+ first <- doFst Relevant (relevance elementSort) value
+ second <- doSnd Relevant (relevance elementSort) value
+
+ first' <- doCast
+ { rel = Relevant
+ , oldType = assert_smaller oldType index.type
+ , newType = assert_smaller newType index'.type
+ , value = first
+ }
+
+ elementType <- subst1 first element
+ elementType' <- subst1 first' element'
+
+ second' <- doCast
+ { rel = relevance elementSort
+ , oldType = assert_smaller oldType elementType
+ , newType = assert_smaller newType elementType'
+ , value = second
+ }
+
+ pure $ Cnstr $ Pair
+ { indexRel = Relevant
+ , elementRel = relevance elementSort
+ , prf = Relevant
+ , first = first'
+ , second = second'
+ }
+doCastHelper
+ oldType@(Sigma {indexSort = Prop, elementSort = elementSort@(Set k), index, element})
+ newType@(Sigma
+ { indexSort = Prop
+ , elementSort = elementSort'
+ , index = index'
+ , element = element'
+ })
+ value = do
+ let Yes Refl = decEq elementSort elementSort'
+ | No _ => pure $ Ntrl $ CastStuck {oldType, newType, value}
+
+ first <- doFst Irrelevant Relevant value
+ second <- doSnd Irrelevant Relevant value
+
+ first' <- doCast
+ { rel = Irrelevant
+ , oldType = assert_smaller oldType index.type
+ , newType = assert_smaller newType index'.type
+ , value = first
+ }
+
+ elementType <- subst1 first element
+ elementType' <- subst1 first' element'
+
+ second' <- doCast
+ { rel = Relevant
+ , oldType = assert_smaller oldType elementType
+ , newType = assert_smaller newType elementType'
+ , value = second
+ }
+
+ pure $ Cnstr $ Pair
+ { indexRel = Irrelevant
+ , elementRel = Relevant
+ , prf = Relevant
+ , first = first'
+ , second = second'
+ }
+doCastHelper Bool Bool value = pure value
+doCastHelper oldType newType value = pure $ Ntrl $ CastStuck {oldType, newType, value}
+
+doCast Irrelevant oldType newType value = pure Irrel
+doCast Relevant (Ntrl oldType) newType value = pure $ Ntrl $ CastL {oldType, newType, value}
+doCast Relevant (Cnstr oldType) (Ntrl newType) value =
+ pure $ Ntrl $ CastR {oldType, newType, value}
+doCast Relevant (Cnstr oldType) (Cnstr newType) value = doCastHelper oldType newType value
export
-doEqual : (r : _) ->
- (a : TypeNormalForm ctx) ->
- NormalForm r ctx ->
- NormalForm r ctx ->
+doEqual : (rel : _) ->
+ (type : TypeNormalForm ctx) ->
+ (left, right : NormalForm rel ctx) ->
LogNormalForm ann Relevant ctx
--- Relies heavily on typing
-doEqualR : (a : Constructor ctx) -> (b : TypeNormalForm ctx) -> LogNormalForm ann Relevant ctx
-doEqualR a (Ntrl b) = pure (Ntrl $ EqualR a b)
-doEqualR (Universe _) (Cnstr (Universe s)) = pure (Cnstr Top)
-doEqualR ty@(Pi s s' var a b) (Cnstr ty'@(Pi l l' _ a' b')) =
- let u : NormalForm (relevance s) (relevance s :: ctx)
- u = point (var, (s ** Refl)) Here
+equalHelper : (left, right : Constructor ctx) -> LogNormalForm ann Relevant ctx
+equalHelper (Universe {s}) (Universe {s = s'}) = pure (Cnstr Top)
+equalHelper
+ left@(Pi {domainSort, codomainSort, domain, codomain})
+ right@(Pi
+ { domainSort = domainSort'
+ , codomainSort = codomainSort'
+ , domain = domain'
+ , codomain = codomain'
+ }) =
+ let y : NormalForm (relevance domainSort) (relevance domainSort :: Irrelevant :: ctx)
+ y = point domain.var Here
in do
- let Yes Refl = decEq (s, s') (l, l')
- | No _ => pure (Ntrl $ EqualStuck ty ty')
- eq1 <- assert_total (doEqual Relevant (cast s) a' a)
- t <- doCast (relevance s) (weaken [relevance s] a') (weaken [relevance s] a) u
- b <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure t) (Right . There)))
- b' <- assert_total (subst' b' (add (LogNormalForm' ann) (Left $ pure u) (Right . There)))
- eq2 <- assert_total (doEqual Relevant (cast s') b b')
- pure (Cnstr $ Sigma Prop Prop "_" eq1 (Cnstr $ Unsorted.weaken [Irrelevant] $ Pi s Prop var a eq2))
-doEqualR ty@(Sigma s s' var a b) (Cnstr ty'@(Sigma l l' _ a' b')) =
- let t : NormalForm (relevance s) (relevance s :: ctx)
- t = point (var, (s ** Refl)) Here
+
+ let Yes Refl = decEq (domainSort, codomainSort) (domainSort', codomainSort')
+ | No _ => pure $ Ntrl $ EqualStuck {left, right}
+
+ domainEqual <- doEqual
+ { rel = Relevant
+ , type = cast domainSort
+ , left = assert_smaller right domain'.type
+ , right = assert_smaller left domain.type
+ }
+
+ let domainType = Sorted.weaken [relevance domainSort, Irrelevant] domain.type
+ let domainType' = Sorted.weaken [relevance domainSort, Irrelevant] domain'.type
+
+ x <- doCast
+ { rel = relevance domainSort
+ , oldType = domainType'
+ , newType = domainType
+ , value = y
+ }
+
+ codomainType <- map1 x (rename codomain (add Elem Here (There . There)))
+ codomainType' <- map1 y (rename codomain' (add Elem Here (There . There)))
+
+ codomainEqual <- doEqual
+ { rel = Relevant
+ , type = cast codomainSort
+ , left = assert_smaller left codomainType
+ , right = assert_smaller right codomainType'
+ }
+
+ let returnElement = Cnstr $ Pi
+ { domainSort = domainSort
+ , codomainSort = Prop
+ , domain = MkDecl Nothing (Sorted.weaken [Irrelevant] domain.type)
+ , codomain = codomainEqual
+ }
+
+ pure $ Cnstr $ Sigma
+ { indexSort = Prop
+ , elementSort = Prop
+ , index = MkDecl Nothing domainEqual
+ , element = returnElement
+ }
+equalHelper
+ left@(Sigma {indexSort, elementSort, index, element})
+ right@(Sigma
+ { indexSort = indexSort'
+ , elementSort = elementSort'
+ , index = index'
+ , element = element'
+ }) =
+ let x : NormalForm (relevance indexSort) (relevance indexSort :: Irrelevant :: ctx)
+ x = point index.var Here
in do
- let Yes Refl = decEq (s, s') (l, l')
- | No _ => pure (Ntrl $ EqualStuck ty ty')
- eq1 <- assert_total (doEqual Relevant (cast s) a a')
- u <- doCast (relevance s) (weaken [relevance s] a) (weaken [relevance s] a') t
- b <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure t) (Right . There)))
- b' <- assert_total (subst' b' (add (LogNormalForm' ann) (Left $ pure u) (Right . There)))
- eq2 <- assert_total (doEqual Relevant (cast s') b b')
- pure (Cnstr $ Sigma Prop Prop "_" eq1 (Cnstr $ Unsorted.weaken [Irrelevant] $ Pi s Prop var a eq2))
-doEqualR Bool (Cnstr Bool) = pure (Cnstr Top)
-doEqualR Top (Cnstr Top) = pure (Cnstr Top)
-doEqualR Bottom (Cnstr Bottom) = pure (Cnstr Top)
-doEqualR a (Cnstr b) = pure (Ntrl $ EqualStuck a b)
-export
-doEqualSet : (a, b : TypeNormalForm ctx) -> LogNormalForm ann Relevant ctx
-doEqualSet (Ntrl a) b = pure (Ntrl $ EqualL a b)
-doEqualSet (Cnstr a) b = doEqualR a b
-
-doEqual Irrelevant a t u = pure (Cnstr Top)
-doEqual Relevant (Ntrl a) t u = pure (Ntrl $ Equal a t u)
-doEqual Relevant (Cnstr (Universe Prop)) t u = do
- pure (Cnstr $ Sigma Prop Prop ""
- (Cnstr $ Pi Prop Prop "" t (Sorted.weaken [Irrelevant] u))
- (Cnstr $ Unsorted.weaken [Irrelevant] $ Pi Prop Prop "" u (Sorted.weaken [Irrelevant] t)))
-doEqual Relevant (Cnstr (Universe (Set _))) t u = doEqualSet t u
-doEqual Relevant (Cnstr (Pi s (Set k) var a b)) t u =
- let x : NormalForm (relevance s) (relevance s :: ctx)
- x = point (var, (s ** Refl)) Here
+ let Yes Refl = decEq (indexSort, elementSort) (indexSort', elementSort')
+ | No _ => pure $ Ntrl $ EqualStuck {left, right}
+
+ indexEqual <- doEqual
+ { rel = Relevant
+ , type = cast indexSort
+ , left = assert_smaller left index.type
+ , right = assert_smaller right index'.type
+ }
+
+ let indexType = Sorted.weaken [relevance indexSort, Irrelevant] index.type
+ let indexType' = Sorted.weaken [relevance indexSort, Irrelevant] index'.type
+
+ y <- doCast
+ { rel = relevance indexSort
+ , oldType = indexType
+ , newType = indexType'
+ , value = x
+ }
+
+ elementType <- map1 x (rename element (add Elem Here (There . There)))
+ elementType' <- map1 y (rename element' (add Elem Here (There . There)))
+
+ elementEqual <- doEqual
+ { rel = Relevant
+ , type = cast elementSort
+ , left = assert_smaller left elementType
+ , right = assert_smaller right elementType'
+ }
+
+ let returnElement = Cnstr $ Pi
+ { domainSort = indexSort
+ , codomainSort = Prop
+ , domain = MkDecl Nothing (Sorted.weaken [Irrelevant] index.type)
+ , codomain = elementEqual
+ }
+
+ pure $ Cnstr $ Sigma
+ { indexSort = Prop
+ , elementSort = Prop
+ , index = MkDecl Nothing indexEqual
+ , element = returnElement
+ }
+equalHelper Bool Bool = pure (Cnstr Top)
+equalHelper left right = pure $ Ntrl $ EqualStuck {left, right}
+
+doEqualType : (left, right : TypeNormalForm ctx) -> LogNormalForm ann Relevant ctx
+doEqualType (Ntrl left) right = pure $ Ntrl $ EqualL {left, right}
+doEqualType (Cnstr left) (Ntrl right) = pure $ Ntrl $ EqualR {left, right}
+doEqualType (Cnstr left) (Cnstr right) = equalHelper left right
+
+doEqual Irrelevant type left right = pure $ Cnstr Top
+doEqual Relevant (Ntrl type) left right = pure $ Ntrl $ Equal {type, left, right}
+doEqual Relevant (Cnstr (Universe {s = Prop})) left right = do
+ let leftToRight = Cnstr $ Pi
+ { domainSort = Prop
+ , codomainSort = Prop
+ , domain = MkDecl Nothing left
+ , codomain = weaken [Irrelevant] right
+ }
+ let rightToLeft = Cnstr $ Pi
+ { domainSort = Prop
+ , codomainSort = Prop
+ , domain = MkDecl Nothing right
+ , codomain = weaken [Irrelevant] left
+ }
+ pure $ Cnstr $ Sigma
+ { indexSort = Prop
+ , elementSort = Prop
+ , index = MkDecl Nothing leftToRight
+ , element = Sorted.weaken [Irrelevant] rightToLeft
+ }
+doEqual Relevant (Cnstr (Universe {s = Set _})) left right = doEqualType left right
+doEqual Relevant (Cnstr (Pi {domainSort, codomainSort, domain, codomain})) left right =
+ let var : NormalForm (relevance domainSort) (relevance domainSort :: ctx)
+ var = point domain.var Here
in do
- t <- assert_total (doApp (weaken [relevance s] t) x)
- u <- assert_total (doApp (weaken [relevance s] u) x)
- eq <- doEqual Relevant b t u
- pure (Cnstr $ Pi s Prop var a eq)
-doEqual Relevant (Cnstr (Sigma s@(Set _) s' var a b)) t u = do
- t1 <- doFst Relevant (relevance s') t
- u1 <- doFst Relevant (relevance s') u
- t2 <- doSnd Relevant (relevance s') t
- u2 <- doSnd Relevant (relevance s') u
- eq1 <- doEqual Relevant a t1 u1
- bt1 <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure t1) Right))
- bu1 <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure u1) Right))
- t2' <- doCast (relevance s') bt1 bu1 t2
- eq2 <- doEqual (relevance s') (assert_smaller b bu1) t2' u2
- pure (Cnstr $ Sigma Prop Prop "_" eq1 (Sorted.weaken [Irrelevant] eq2))
-doEqual Relevant (Cnstr (Sigma Prop (Set k) var a b)) t u = do
- t2 <- doSnd Irrelevant Relevant t
- u2 <- doSnd Irrelevant Relevant u
- bt1 <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure $ Irrel) Right))
- bu1 <- assert_total (subst' b (add (LogNormalForm' ann) (Left $ pure $ Irrel) Right))
- t2' <- doCast Relevant bt1 bu1 t2
- eq2 <- doEqual Relevant (assert_smaller b bu1) t2' u2
- pure (Cnstr $ Sigma Prop Prop "_" (Cnstr Top) (Sorted.weaken [Irrelevant] eq2))
-doEqual Relevant (Cnstr Bool) t u = do
- relevant <- doIf u (Cnstr Top) (Cnstr Bottom)
- irrelevant <- doIf u (Cnstr Bottom) (Cnstr Top)
- doIf t relevant irrelevant
-doEqual Relevant (Cnstr a) t u = inScope "wrong constructor for equal" $ fatal a
+
+ leftApp <- doApp (weaken [relevance domainSort] left) var
+ rightApp <- doApp (weaken [relevance domainSort] right) var
+
+ equality <- doEqual
+ { rel = Relevant
+ , type = codomain
+ , left = assert_smaller left leftApp
+ , right = assert_smaller right rightApp
+ }
+
+ pure $ Cnstr $ Pi {domainSort, codomainSort = Prop, domain, codomain = equality}
+doEqual
+ Relevant
+ (Cnstr (Sigma {indexSort = indexSort@(Set _), elementSort, index, element}))
+ left
+ right = do
+ leftFirst <- doFst Relevant (relevance elementSort) left
+ rightFirst <- doFst Relevant (relevance elementSort) right
+ leftSecond <- doSnd Relevant (relevance elementSort) left
+ rightSecond <- doSnd Relevant (relevance elementSort) right
+
+ leftEquality <- doEqual
+ { rel = Relevant
+ , type = index.type
+ , left = assert_smaller left leftFirst
+ , right = assert_smaller right rightFirst
+ }
+
+ leftElementType <- subst1 leftFirst element
+ rightElementType <- subst1 rightFirst element
+
+ leftSecond <- doCast (relevance elementSort) leftElementType rightElementType leftSecond
+
+ rightEquality <- doEqual
+ { rel = relevance elementSort
+ , type = rightElementType
+ , left = assert_smaller left leftSecond
+ , right = assert_smaller right rightSecond
+ }
+
+ pure $ Cnstr $ Sigma
+ { indexSort = Prop
+ , elementSort = Prop
+ , index = MkDecl Nothing leftEquality
+ , element = Sorted.weaken [Irrelevant] rightEquality
+ }
+doEqual
+ Relevant
+ (Cnstr (Sigma {indexSort = Prop, elementSort = elementSort@(Set _), index, element}))
+ left
+ right = do
+ leftFirst <- doFst Irrelevant Relevant left
+ rightFirst <- doFst Irrelevant Relevant right
+ leftSecond <- doSnd Irrelevant Relevant left
+ rightSecond <- doSnd Irrelevant Relevant right
+
+ leftEquality <- doEqual
+ { rel = Irrelevant
+ , type = index.type
+ , left = assert_smaller left leftFirst
+ , right = assert_smaller right rightFirst
+ }
+
+ leftElementType <- subst1 leftFirst element
+ rightElementType <- subst1 rightFirst element
+
+ leftSecond <- doCast Relevant leftElementType rightElementType leftSecond
+
+ rightEquality <- doEqual
+ { rel = Relevant
+ , type = rightElementType
+ , left = assert_smaller left leftSecond
+ , right = assert_smaller right rightSecond
+ }
+
+ pure $ Cnstr $ Sigma
+ { indexSort = Prop
+ , elementSort = Prop
+ , index = MkDecl Nothing leftEquality
+ , element = Sorted.weaken [Irrelevant] rightEquality
+ }
+doEqual Relevant (Cnstr Bool) left right = do
+ whenLeftTrue <- doIf right (Cnstr Top) (Cnstr Bottom)
+ whenLeftFalse <- doIf right (Cnstr Bottom) (Cnstr Top)
+ doIf left whenLeftTrue whenLeftFalse
+doEqual Relevant (Cnstr t) left right = inScope "wrong constructor for equal" $ fatal t
+
+substDecl : DeclForm ~|> Hom (LogNormalForm' ann) (LogDeclForm ann)
+substDecl (MkDecl var type) f = pure (MkDecl var !(subst' type f))
substCnstr : Constructor ~|> Hom (LogNormalForm' ann) (LogConstructor ann)
-substCnstr (Universe s) f = pure (Universe s)
-substCnstr (Pi s s' var a b) f = do
- a <- subst' a f
- b <- subst' b (lift [(_ ** (var, (s ** Refl)))] f)
- pure (Pi s s' var a b)
-substCnstr (Lambda s var t) f = do
- t <- subst' t (lift [(_ ** (var, (s ** Refl)))] f)
- pure (Lambda s var t)
-substCnstr (Sigma s s' var a b) f = do
- a <- subst' a f
- b <- subst' b (lift [(_ ** (var, (s ** Refl)))] f)
- pure (Sigma s s' var a b)
-substCnstr (Pair s s' prf t u) f = do
- t <- subst' t f
- u <- subst' u f
- pure (Pair s s' prf t u)
+substCnstr (Universe {s}) f = pure (Universe {s})
+substCnstr (Pi {domainSort, codomainSort, domain, codomain}) f = do
+ domain <- substDecl domain f
+ codomain <- subst' codomain (lift [(_ ** domain.var)] f)
+ pure (Pi {domainSort, codomainSort, domain, codomain})
+substCnstr (Lambda {domainRel, var, body}) f = do
+ body <- subst' body (lift [(_ ** var)] f)
+ pure (Lambda {domainRel, var, body})
+substCnstr (Sigma {indexSort, elementSort, index, element}) f = do
+ index <- substDecl index f
+ element <- subst' element (lift [(_ ** index.var)] f)
+ pure (Sigma {indexSort, elementSort, index, element})
+substCnstr (Pair {indexRel, elementRel, prf, first, second}) f = do
+ first <- subst' first f
+ second <- subst' second f
+ pure (Pair {indexRel, elementRel, prf, first, second})
substCnstr Bool f = pure Bool
substCnstr True f = pure True
substCnstr False f = pure False
@@ -245,57 +514,58 @@ substCnstr Top f = pure Top
substCnstr Bottom f = pure Bottom
substNtrl : Neutral ~|> Hom (LogNormalForm' ann) (LogNormalForm ann Relevant)
-substNtrl (Var var sort prf i) f = case f i of
+substNtrl (Var {var, i}) f = case f i of
Left t => t
- Right j => pure (Ntrl $ Var var sort prf j)
-substNtrl (App r t u) f = do
- t <- substNtrl t f
- u <- subst' u f
- assert_total (doApp t u)
-substNtrl (Fst r t) f = do
- t <- substNtrl t f
- doFst Relevant r t
-substNtrl (Snd r t) f = do
- t <- substNtrl t f
- doSnd r Relevant $ rewrite pairRelevantRight r in t
-substNtrl (If t u v) f = do
- t <- substNtrl t f
- u <- subst' u f
- v <- subst' v f
- doIf t u v
+ Right i => pure $ Ntrl $ Var {var, i}
+substNtrl (App {argRel, fun, arg}) f = do
+ fun <- substNtrl fun f
+ arg <- subst' arg f
+ assert_total (doApp fun arg)
+substNtrl (First {secondRel, arg}) f = do
+ arg <- substNtrl arg f
+ doFst Relevant secondRel arg
+substNtrl (Second {firstRel, arg}) f = do
+ arg <- substNtrl arg f
+ let arg = rewrite pairRelevantRight firstRel in arg
+ doSnd firstRel Relevant arg
+substNtrl (If {discriminant, true, false}) f = do
+ discriminant <- substNtrl discriminant f
+ true <- subst' true f
+ false <- subst' false f
+ doIf discriminant true false
substNtrl Absurd f = pure (doAbsurd Relevant)
-substNtrl (Equal a t u) f = do
- a <- substNtrl a f
- t <- subst' t f
- u <- subst' u f
- doEqual _ a t u
-substNtrl (EqualL a b) f = do
- a <- substNtrl a f
- b <- subst' b f
- doEqualSet a b
-substNtrl (EqualR a b) f = do
- a <- substCnstr a f
- b <- substNtrl b f
- doEqualR a b
-substNtrl (EqualStuck a b) f = do
- a <- substCnstr a f
- b <- substCnstr b f
- pure (Ntrl $ EqualStuck a b)
-substNtrl (CastL a b t) f = do
- a <- substNtrl a f
- b <- subst' b f
- t <- subst' t f
- doCast _ a b t
-substNtrl (CastR a b t) f = do
- a <- substCnstr a f
- b <- substNtrl b f
- t <- subst' t f
- doCastR a b t
-substNtrl (CastStuck a b t) f = do
- a <- substCnstr a f
- b <- substCnstr b f
- t <- subst' t f
- pure (Ntrl $ CastStuck a b t)
+substNtrl (Equal {type, left, right}) f = do
+ type <- substNtrl type f
+ left <- subst' left f
+ right <- subst' right f
+ assert_total (doEqual Relevant type left right)
+substNtrl (EqualL {left, right}) f = do
+ left <- substNtrl left f
+ right <- subst' right f
+ assert_total (doEqualType left right)
+substNtrl (EqualR {left, right}) f = do
+ left <- substCnstr left f
+ right <- substNtrl right f
+ assert_total (doEqualType (Cnstr left) right)
+substNtrl (EqualStuck {left, right}) f = do
+ left <- substCnstr left f
+ right <- substCnstr right f
+ assert_total (doEqualType (Cnstr left) (Cnstr right))
+substNtrl (CastL {oldType, newType, value}) f = do
+ oldType <- substNtrl oldType f
+ newType <- subst' newType f
+ value <- subst' value f
+ assert_total (doCast Relevant oldType newType value)
+substNtrl (CastR {oldType, newType, value}) f = do
+ oldType <- substCnstr oldType f
+ newType <- substNtrl newType f
+ value <- subst' value f
+ assert_total (doCast Relevant (Cnstr oldType) newType value)
+substNtrl (CastStuck {oldType, newType, value}) f = do
+ oldType <- substCnstr oldType f
+ newType <- substCnstr newType f
+ value <- subst' value f
+ assert_total (doCast Relevant (Cnstr oldType) (Cnstr newType) value)
subst' (Ntrl t) f = substNtrl t f
subst' (Cnstr t) f = pure $ Cnstr !(substCnstr t f)
@@ -304,9 +574,3 @@ subst' Irrel f = pure Irrel
export
subst : NormalForm ~|> Hom (LogNormalForm ann) (LogNormalForm ann)
subst t f = subst' t (Left . f)
-
--- Utilities -------------------------------------------------------------------
-
-export
-subst1 : {s' : _} -> NormalForm s ctx -> NormalForm s' (s :: ctx) -> LogNormalForm ann s' ctx
-subst1 t u = subst' u (add (LogNormalForm' ann) (Left $ pure t) Right)
diff --git a/src/Obs/Parser.idr b/src/Obs/Parser.idr
index 68591ee..b00f5a8 100644
--- a/src/Obs/Parser.idr
+++ b/src/Obs/Parser.idr
@@ -29,11 +29,6 @@ data ObsTokenKind
| OTTrue
| OTFalse
| OTIf
- | OTContainer
- | OTTag
- | OTPosition
- | OTNext
- | OTSem
| OTPoint
| OTVoid
| OTAbsurd
@@ -43,7 +38,6 @@ data ObsTokenKind
| OTCastRefl
-- Special symbols
| OTUnit
- | OTTriangle
-- Grouping symbols
| OTPOpen
| OTPClose
@@ -59,7 +53,6 @@ data ObsTokenKind
| OTTilde
| OTEqual
| OTColon
- | OTPipe
Eq ObsTokenKind where
OTNewlines == OTNewlines = True
@@ -74,11 +67,6 @@ Eq ObsTokenKind where
OTTrue == OTTrue = True
OTFalse == OTFalse = True
OTIf == OTIf = True
- OTContainer == OTContainer = True
- OTTag == OTTag = True
- OTPosition == OTPosition = True
- OTNext == OTNext = True
- OTSem == OTSem = True
OTPoint == OTPoint = True
OTVoid == OTVoid = True
OTAbsurd == OTAbsurd = True
@@ -87,7 +75,6 @@ Eq ObsTokenKind where
OTCast == OTCast = True
OTCastRefl == OTCastRefl = True
OTUnit == OTUnit = True
- OTTriangle == OTTriangle = True
OTPOpen == OTPOpen = True
OTPClose == OTPClose = True
OTAOpen == OTAOpen = True
@@ -101,9 +88,43 @@ Eq ObsTokenKind where
OTTilde == OTTilde = True
OTEqual == OTEqual = True
OTColon == OTColon = True
- OTPipe == OTPipe = True
_ == _ = False
+Show ObsTokenKind where
+ show OTNewlines = "\\n"
+ show OTSpaces = " "
+ show OTIdent = "ident"
+ show OTProp = "Prop"
+ show OTSet = "Set"
+ show OTNat = "nat"
+ show OTFst = "fst"
+ show OTSnd = "snd"
+ show OTBool = "Bool"
+ show OTTrue = "True"
+ show OTFalse = "False"
+ show OTIf = "if"
+ show OTPoint = "tt"
+ show OTVoid = "Void"
+ show OTAbsurd = "absurd"
+ show OTRefl = "refl"
+ show OTTransp = "transp"
+ show OTCast = "cast"
+ show OTCastRefl = "castRefl"
+ show OTUnit = "()"
+ show OTPOpen = "("
+ show OTPClose = ")"
+ show OTAOpen = "<"
+ show OTAClose = ">"
+ show OTBackslash = "\\"
+ show OTSlash = "/"
+ show OTThinArrow = "->"
+ show OTFatArrow = "=>"
+ show OTProduct = "**"
+ show OTComma = ","
+ show OTTilde = "~"
+ show OTEqual = "="
+ show OTColon = ":"
+
TokenKind ObsTokenKind where
TokType OTIdent = String
TokType OTNat = Nat
@@ -121,11 +142,6 @@ TokenKind ObsTokenKind where
tokValue OTTrue s = ()
tokValue OTFalse s = ()
tokValue OTIf s = ()
- tokValue OTContainer s = ()
- tokValue OTTag s = ()
- tokValue OTPosition s = ()
- tokValue OTNext s = ()
- tokValue OTSem s = ()
tokValue OTPoint s = ()
tokValue OTVoid s = ()
tokValue OTAbsurd s = ()
@@ -134,7 +150,6 @@ TokenKind ObsTokenKind where
tokValue OTCast s = ()
tokValue OTCastRefl s = ()
tokValue OTUnit s = ()
- tokValue OTTriangle s = ()
tokValue OTPOpen s = ()
tokValue OTPClose s = ()
tokValue OTAOpen s = ()
@@ -148,7 +163,6 @@ TokenKind ObsTokenKind where
tokValue OTTilde s = ()
tokValue OTEqual s = ()
tokValue OTColon s = ()
- tokValue OTPipe s = ()
ObsToken : Type
ObsToken = Token ObsTokenKind
@@ -166,11 +180,6 @@ Show ObsToken where
show (Tok OTTrue s) = "True"
show (Tok OTFalse s) = "False"
show (Tok OTIf s) = "if"
- show (Tok OTContainer s) = "Container"
- show (Tok OTTag s) = "tag"
- show (Tok OTPosition s) = "position"
- show (Tok OTNext s) = "next"
- show (Tok OTSem s) = "sem"
show (Tok OTPoint s) = "tt"
show (Tok OTVoid s) = "Void"
show (Tok OTAbsurd s) = "absurd"
@@ -179,7 +188,6 @@ Show ObsToken where
show (Tok OTCast s) = "cast"
show (Tok OTCastRefl s) = "castRefl"
show (Tok OTUnit s) = "()"
- show (Tok OTTriangle s) = "<|"
show (Tok OTPOpen s) = "("
show (Tok OTPClose s) = ")"
show (Tok OTAOpen s) = "<"
@@ -193,7 +201,6 @@ Show ObsToken where
show (Tok OTTilde s) = "~"
show (Tok OTEqual s) = "="
show (Tok OTColon s) = ":"
- show (Tok OTPipe s) = "|"
identifier : Lexer
identifier = alpha <+> many alphaNum
@@ -208,11 +215,6 @@ keywords =
, ("True", OTTrue)
, ("False", OTFalse)
, ("if", OTIf)
- , ("Container", OTContainer)
- , ("tag", OTTag)
- , ("position", OTPosition)
- , ("next", OTNext)
- , ("sem", OTSem)
, ("tt", OTPoint)
, ("Void", OTVoid)
, ("absurd", OTAbsurd)
@@ -243,7 +245,6 @@ obsTokenMap = toTokenMap [(newlines, OTNewlines), (spaces, OTSpaces)] ++
, (exact "~", OTTilde)
, (exact "=", OTEqual)
, (exact ":", OTColon)
- , (exact "|", OTPipe)
]
op : Type -> Type -> Nat -> Type
@@ -264,66 +265,77 @@ termForms =
, (OTUnit, Top)
]
-headForms : List (ObsTokenKind, (n ** (Vect (S n) (WithBounds Syntax) -> Syntax)))
+headForms : List (ObsTokenKind, (n ** op (WithBounds Syntax) Syntax (S n)))
headForms =
- [ (OTFst, (0 ** uncurry 1 First))
- , (OTSnd, (0 ** uncurry 1 Second))
- , (OTAbsurd, (0 ** uncurry 1 Absurd))
- , (OTRefl, (0 ** uncurry 1 Refl))
- , (OTTransp, (4 ** (uncurry 5 Transp)))
- , (OTCast, (3 ** uncurry 4 Cast))
- , (OTCastRefl, (0 ** uncurry 1 CastId))
+ [ (OTFst, (0 ** First))
+ , (OTSnd, (0 ** Second))
+ , (OTAbsurd, (0 ** Absurd))
+ , (OTRefl, (0 ** Refl))
+ , (OTTransp, (4 ** Transp))
+ , (OTCast, (3 ** Cast))
+ , (OTCastRefl, (0 ** CastId))
]
-headLambdaForms : List (ObsTokenKind, (n ** ((WithBounds String, WithBounds Syntax) -> Vect n (WithBounds Syntax) -> Syntax)))
-headLambdaForms =
- [ (OTIf, (3 ** (uncurry 3 . uncurry If)))
- ]
+headLambdaForms : List (ObsTokenKind, (n ** (LambdaForm -> op (WithBounds Syntax) Syntax n)))
+headLambdaForms = [(OTIf, (3 ** If))]
-declForms : List (ObsTokenKind, (WithBounds String -> op (WithBounds Syntax) Syntax 2))
-declForms = [(OTThinArrow, Pi), (OTProduct, Sigma)]
+declForms : List (ObsTokenKind, (n ** op DeclForm (WithBounds Syntax -> Syntax) (S n)))
+declForms =
+ [ (OTThinArrow, (0 ** Pi))
+ , (OTProduct, (0 ** Sigma))
+ ]
count : (n : _) -> Grammar state tok True a -> Grammar state tok (isSucc n) (Vect n a)
count 0 p = pure []
count (S n) p = [| p :: count n p |]
+match' : (tok : ObsTokenKind) -> Grammar state ObsToken True (TokType tok)
+match' tok = do
+ pos <- position
+ token <- peek
+ let True = token.kind == tok
+ | False => failLoc pos "expected \{show tok}"
+ match tok
+
ident : Grammar state ObsToken True (WithBounds String)
-ident = bounds $ match OTIdent
+ident = bounds $ match' OTIdent
whitespace : Grammar state ObsToken True ()
-whitespace = map (\_ => ()) $ some (optional (match OTNewlines) *> match OTSpaces)
+whitespace = map (\_ => ()) $ some (optional (match' OTNewlines) *> match' OTSpaces)
parens : Lazy (Grammar state ObsToken True a) -> Grammar state ObsToken True a
-parens p = match OTPOpen *> optional whitespace *> p <* optional whitespace <* match OTPClose
+parens p = match' OTPOpen *> optional whitespace *> p <* optional whitespace <* match' OTPClose
var : Grammar state ObsToken True (WithBounds Syntax)
var = map (map Var) ident
noArgUniverse : Grammar state ObsToken True (WithBounds Universe)
noArgUniverse = bounds $
- map (const Prop) (match OTProp <* commit) <|>
- map (const (Set 0)) (match OTSet <* commit)
+ map (const Prop) (match' OTProp <* commit) <|>
+ map (const (Set 0)) (match' OTSet <* commit)
universe : Grammar state ObsToken True (WithBounds Universe)
universe = bounds $
- map (const Prop) (match OTProp <* commit) <|>
- map Set (match OTSet *> commit *> option 0 (match OTNat <* commit))
+ map (const Prop) (match' OTProp <* commit) <|>
+ map Set (match' OTSet *> commit *> option 0 (match' OTNat <* commit))
-decl : Lazy (Grammar state ObsToken True a) -> Grammar state ObsToken True (WithBounds String, a)
-decl p = [| MkPair (ident <* whitespace <* match OTColon <* whitespace) p |]
+decl : Lazy (Grammar state ObsToken True (WithBounds Syntax)) ->
+ Grammar state ObsToken True DeclForm
+decl p = [| MkDecl (ident <* whitespace <* match' OTColon <* whitespace) p |]
pair : Lazy (Grammar state ObsToken True a) -> Grammar state ObsToken True (a, a)
pair p =
- match OTAOpen *> commit *>
+ match' OTAOpen *> commit *>
[| MkPair
- (optional whitespace *> p <* optional whitespace <* match OTComma <* commit)
+ (optional whitespace *> p <* optional whitespace <* match' OTComma <* commit)
(optional whitespace *> p <* optional whitespace) |]
- <* match OTAClose <* commit
+ <* match' OTAClose <* commit
-lambda : Lazy (Grammar state ObsToken True a) -> Grammar state ObsToken True (WithBounds String, a)
+lambda : Lazy (Grammar state ObsToken True (WithBounds Syntax)) ->
+ Grammar state ObsToken True LambdaForm
lambda p =
- match OTBackslash *> commit *>
- [| MkPair (ident <* whitespace <* match OTFatArrow <* whitespace) p |]
+ match' OTBackslash *> commit *>
+ [| MkLambda (ident <* whitespace <* match' OTFatArrow <* whitespace) p |]
partial
noUniversesTerm : Grammar state ObsToken True (WithBounds Syntax)
@@ -334,8 +346,6 @@ head : Grammar state ObsToken True (WithBounds Syntax)
partial
spine : Grammar state ObsToken True (WithBounds Syntax)
partial
-container : Grammar state ObsToken True (WithBounds Syntax)
-partial
equals : Grammar state ObsToken True (WithBounds Syntax)
partial
exp : Grammar state ObsToken True (WithBounds Syntax)
@@ -344,7 +354,7 @@ noUniversesTerm =
parens exp <|>
var <|>
bounds (map (uncurry Pair) (pair exp)) <|>
- bounds (choiceMap (\(k, s) => map (const s) (match k)) termForms)
+ bounds (choiceMap (\(k, s) => map (const s) (match' k)) termForms)
term = noUniversesTerm <|> map (map Universe) noArgUniverse
@@ -353,54 +363,52 @@ head =
map (map Universe) universe <|>
bounds
(choiceMap
- (\(hd, (n ** f)) => match hd *> commit *>
- [| f (whitespace *> parens (lambda exp)) (count n (whitespace *> term))|])
+ (\(hd, (n ** f)) =>
+ match' hd *> commit *> whitespace *>
+ pure (uncurry n . f) <*> parens (lambda exp) <*> count n (whitespace *> term))
headLambdaForms) <|>
bounds
(choiceMap
- (\(hd, (n ** f)) => match hd *> commit *> [| f (count (S n) (whitespace *> term)) |])
+ (\(hd, (n ** f)) => match' hd *> commit *>
+ pure (uncurry (S n) f) <*> count (S n) (whitespace *> term))
headForms)
spine = map (uncurry $ foldl (\t, u => joinBounds (map (\_ => map (\_ => App t u) u) t))) $
[| MkPair head (many (whitespace *> term)) |]
-container = spine
-
equals = map (\(t, u) => maybe t (\u => joinBounds (map (\_ => map (\_ => Equal t u) u) t)) u) $
- [| MkPair container (optional (whitespace *> match OTTilde *> commit *> whitespace *> container)) |]
+ [| MkPair spine (optional (whitespace *> match' OTTilde *> commit *> whitespace *> spine)) |]
exp =
equals <|>
- bounds (map (uncurry Lambda) $ lambda exp) <|>
+ bounds (map Lambda $ lambda exp) <|>
bounds
- (map (\((var, a), (b, f)) => f var a b) $
- [| MkPair
- (parens (decl exp) <* whitespace)
- (choiceMap
- (\(op, f) => match op *> commit *> whitespace *> [| MkPair exp (pure f) |])
- declForms)
- |])
+ (choiceMap
+ (\(sep, (n ** f)) =>
+ pure (uncurry (S n) f) <*>
+ count (S n) (parens (decl exp) <* whitespace <* match' sep <* commit <* whitespace) <*>
+ exp)
+ declForms)
partial
def : Grammar state ObsToken True (WithBounds String, WithBounds Syntax)
-def = [| MkPair (ident <* whitespace <* match OTEqual <* whitespace) exp |]
+def = [| MkPair (ident <* whitespace <* match' OTEqual <* whitespace) exp |]
partial
fullDef : Grammar state ObsToken True Definition
fullDef =
seq
- [| MkPair (decl exp <* commit) (optional whitespace *> match OTNewlines *> def <* commit) |]
- (\((name, ty), (name', tm)) =>
+ [| MkPair (decl exp <* commit) (optional whitespace *> match' OTNewlines *> def <* commit) |]
+ (\((MkDecl name ty), (name', tm)) =>
if name.val == name'.val
then pure (MkDefinition {name = name, ty, tm})
- else fatalLoc name.bounds "name mismatch for declaration and definition")
+ else fatalLoc name.bounds "name mismatch' for declaration and definition")
partial
file : Grammar state ObsToken False (List Definition)
file =
- optional (whitespace *> match OTNewlines) *>
- sepEndBy (optional whitespace *> match OTNewlines) (fullDef <* commit)
- -- <* eof
+ optional (whitespace *> match' OTNewlines) *>
+ sepEndBy (optional whitespace *> match' OTNewlines) (fullDef <* commit)
whitespaceIrrelevant : WithBounds ObsToken -> WithBounds ObsToken
whitespaceIrrelevant a = case (a.val.kind) of
@@ -413,7 +421,6 @@ mergeToks : List (WithBounds ObsToken) -> List (WithBounds ObsToken)
mergeToks (a :: tail@(b :: rest)) = case (a.val.kind, b.val.kind) of
(OTSpaces, OTNat) => mergeBounds a b :: mergeToks rest
(OTPOpen, OTPClose) => map (\_ => (Tok OTUnit "()")) (mergeBounds a b) :: mergeToks rest
- (OTAOpen, OTPipe) => map (\_ => (Tok OTTriangle "<|")) (mergeBounds a b) :: mergeToks rest
_ => a :: mergeToks tail
mergeToks toks = toks
@@ -425,7 +432,7 @@ castErr (Right x) = pure x
castErr (Left errs) = do
for_ {b = ()} errs
(\(Error msg bounds) =>
- inBounds $ map error $ maybe (irrelevantBounds msg) (MkBounded msg True) bounds)
+ inBounds $ map error $ maybe (irrelevantBounds msg) (MkBounded msg False) bounds)
abort
partial
diff --git a/src/Obs/Pretty.idr b/src/Obs/Pretty.idr
index 52a358c..bd163ee 100644
--- a/src/Obs/Pretty.idr
+++ b/src/Obs/Pretty.idr
@@ -4,19 +4,22 @@ import public Text.PrettyPrint.Prettyprinter
-- ty is rendered Open
export
-prettyDecl : (name : String) -> (ty : Doc ann) -> Doc ann
-prettyDecl name ty = parens $ group (pretty name <++> colon <+> line <+> align ty)
+prettyDecl : (name : Maybe String) -> (ty : Doc ann) -> Doc ann
+prettyDecl Nothing ty = parens $ group $ align ty
+prettyDecl (Just name) ty = parens $ group (pretty name <++> colon <+> line <+> align ty)
--- ty and tail are rendered Open
+-- names are rendered Open
export
prettyDeclForm : (prec : Prec) ->
- (name : String) ->
- (ty : Doc ann) ->
+ (decls : List (Doc ann)) ->
(sep : String) ->
(tail : Doc ann) ->
Doc ann
-prettyDeclForm d name ty sep tail =
- parenthesise (d > Open) $ group $ vsep $ [prettyDecl name ty <++> pretty sep, align tail]
+prettyDeclForm d decls sep tail =
+ parenthesise (d > Open) $
+ group $
+ concatWith (\x, y => x <++> pretty sep <+> line <+> y) $
+ decls ++ [align tail]
-- body is rendered Open
export
diff --git a/src/Obs/Syntax.idr b/src/Obs/Syntax.idr
index a141d28..74e15c2 100644
--- a/src/Obs/Syntax.idr
+++ b/src/Obs/Syntax.idr
@@ -10,17 +10,31 @@ import Text.Bounded
-- Definition ------------------------------------------------------------------
+data Syntax : Type
+
+public export
+record DeclForm where
+ constructor MkDecl
+ var : WithBounds String
+ type : WithBounds Syntax
+
+public export
+record LambdaForm where
+ constructor MkLambda
+ var : WithBounds String
+ body : WithBounds Syntax
+
public export
data Syntax : Type where
Var : (var : String) -> Syntax
-- Universes
Universe : (s : Universe) -> Syntax
-- Dependent Products
- Pi : (var : WithBounds String) -> (domain, codomain : WithBounds Syntax) -> Syntax
- Lambda : (var : WithBounds String) -> (body : WithBounds Syntax) -> Syntax
+ Pi : (domain : DeclForm) -> (codomain : WithBounds Syntax) -> Syntax
+ Lambda : (body : LambdaForm) -> Syntax
App : (fun, arg : WithBounds Syntax) -> Syntax
-- Dependent Sums
- Sigma : (var : WithBounds String) -> (index, element : WithBounds Syntax) -> Syntax
+ Sigma : (index : DeclForm) -> (element : WithBounds Syntax) -> Syntax
Pair : (first, second : WithBounds Syntax) -> Syntax
First : (arg : WithBounds Syntax) -> Syntax
Second : (arg : WithBounds Syntax) -> Syntax
@@ -28,9 +42,7 @@ data Syntax : Type where
Bool : Syntax
True : Syntax
False : Syntax
- If : (var : WithBounds String) ->
- (returnType, discriminant, true, false : WithBounds Syntax) ->
- Syntax
+ If : (returnType : LambdaForm) -> (discriminant, true, false : WithBounds Syntax) -> Syntax
-- True
Top : Syntax
Point : Syntax
@@ -55,15 +67,21 @@ record Definition where
prettyPrecBounds : Prec -> WithBounds Syntax -> Doc ann
+prettyPrecDecl : DeclForm -> Doc ann
+prettyPrecDecl (MkDecl var type) = prettyDecl (Just var.val) (prettyPrecBounds Open type)
+
+prettyPrecLambda : Prec -> LambdaForm -> Doc ann
+prettyPrecLambda d (MkLambda var body) = prettyLambda d var.val (prettyPrecBounds Open body)
+
prettyPrec : Prec -> Syntax -> Doc ann
prettyPrec d (Var {var}) = pretty var
prettyPrec d (Universe {s}) = prettyPrec d s
-prettyPrec d (Pi {var, domain, codomain}) =
- prettyDeclForm d var.val (prettyPrecBounds Open domain) "->" (prettyPrecBounds Open codomain)
-prettyPrec d (Lambda {var, body}) = prettyLambda d var.val (prettyPrecBounds Open body)
+prettyPrec d (Pi {domain, codomain}) =
+ prettyDeclForm d [prettyPrecDecl domain] "->" (prettyPrecBounds Open codomain)
+prettyPrec d (Lambda {body}) = prettyPrecLambda d body
prettyPrec d (App {fun, arg}) = prettyApp d (prettyPrecBounds Open fun) [prettyPrecBounds App arg]
-prettyPrec d (Sigma {var, index, element}) =
- prettyDeclForm d var.val (prettyPrecBounds Open index) "**" (prettyPrecBounds Open element)
+prettyPrec d (Sigma {index, element}) =
+ prettyDeclForm d [prettyPrecDecl index] "**" (prettyPrecBounds Open element)
prettyPrec d (Pair {first, second}) =
prettyPair (prettyPrecBounds Open first) (prettyPrecBounds Open second)
prettyPrec d (First {arg}) = prettyApp d (pretty "fst") [prettyPrecBounds App arg]
@@ -71,9 +89,9 @@ prettyPrec d (Second {arg}) = prettyApp d (pretty "snd") [prettyPrecBounds App a
prettyPrec d Bool = pretty "Bool"
prettyPrec d True = pretty "True"
prettyPrec d False = pretty "False"
-prettyPrec d (If {var, returnType, discriminant, true, false}) =
+prettyPrec d (If {returnType, discriminant, true, false}) =
prettyApp d (pretty "if") $
- [ prettyLambda App var.val (prettyPrecBounds Open returnType)
+ [ prettyPrecLambda App returnType
, prettyPrecBounds App discriminant
, prettyPrecBounds App true
, prettyPrecBounds App false
diff --git a/src/Obs/Term.idr b/src/Obs/Term.idr
index 95ed08b..8dad72c 100644
--- a/src/Obs/Term.idr
+++ b/src/Obs/Term.idr
@@ -12,21 +12,33 @@ import Text.Bounded
-- Definition ------------------------------------------------------------------
+data Term : Nat -> Type
+
+public export
+record DeclForm (n : Nat) where
+ constructor MkDecl
+ var : WithBounds String
+ type : WithBounds (Term n)
+
+public export
+record LambdaForm (n : Nat) where
+ constructor MkLambda
+ var : WithBounds String
+ body : WithBounds (Term (S n))
+
public export
data Term : Nat -> Type where
Var : (var : String) -> (i : Fin n) -> Term n
-- Universes
Universe : (s : Universe) -> Term n
-- Dependent Product
- Pi : (var : WithBounds String) ->
- (domain : WithBounds (Term n)) ->
+ Pi : (domain : DeclForm n) ->
(codomain : WithBounds (Term (S n))) ->
Term n
- Lambda : (var : WithBounds String) -> (body : WithBounds (Term (S n))) -> Term n
+ Lambda : (body : LambdaForm n) -> Term n
App : (fun, arg : WithBounds (Term n)) -> Term n
-- Dependent Sums
- Sigma : (var : WithBounds String) ->
- (index : WithBounds (Term n)) ->
+ Sigma : (index : DeclForm n) ->
(element : WithBounds (Term (S n))) ->
Term n
Pair : (first, second : WithBounds (Term n)) -> Term n
@@ -36,8 +48,7 @@ data Term : Nat -> Type where
Bool : Term n
True : Term n
False : Term n
- If : (var : WithBounds String) ->
- (returnType : WithBounds (Term (S n))) ->
+ If : (returnType : LambdaForm n) ->
(discriminant, true, false : WithBounds (Term n)) ->
Term n
-- True
@@ -69,15 +80,21 @@ data Block : Nat -> Type where
prettyPrecBounds : Prec -> WithBounds (Term n) -> Doc ann
+prettyPrecDecl : DeclForm n -> Doc ann
+prettyPrecDecl (MkDecl var type) = prettyDecl (Just var.val) (prettyPrecBounds Open type)
+
+prettyPrecLambda : Prec -> LambdaForm n -> Doc ann
+prettyPrecLambda d (MkLambda var body) = prettyLambda d var.val (prettyPrecBounds Open body)
+
prettyPrec : Prec -> Term n -> Doc ann
prettyPrec d (Var {var, i}) = pretty var
prettyPrec d (Universe {s}) = prettyPrec d s
-prettyPrec d (Pi {var, domain, codomain}) =
- prettyDeclForm d var.val (prettyPrecBounds Open domain) "->" (prettyPrecBounds Open codomain)
-prettyPrec d (Lambda {var, body}) = prettyLambda d var.val (prettyPrecBounds Open body)
+prettyPrec d (Pi {domain, codomain}) =
+ prettyDeclForm d [prettyPrecDecl domain] "->" (prettyPrecBounds Open codomain)
+prettyPrec d (Lambda {body}) = prettyPrecLambda d body
prettyPrec d (App {fun, arg}) = prettyApp d (prettyPrecBounds Open fun) [prettyPrecBounds App arg]
-prettyPrec d (Sigma {var, index, element}) =
- prettyDeclForm d var.val (prettyPrecBounds Open index) "**" (prettyPrecBounds Open element)
+prettyPrec d (Sigma {index, element}) =
+ prettyDeclForm d [prettyPrecDecl index] "**" (prettyPrecBounds Open element)
prettyPrec d (Pair {first, second}) =
prettyPair (prettyPrecBounds Open first) (prettyPrecBounds Open second)
prettyPrec d (First {arg}) = prettyApp d (pretty "fst") [prettyPrecBounds App arg]
@@ -85,9 +102,9 @@ prettyPrec d (Second {arg}) = prettyApp d (pretty "snd") [prettyPrecBounds App a
prettyPrec d Bool = pretty "Bool"
prettyPrec d True = pretty "True"
prettyPrec d False = pretty "False"
-prettyPrec d (If {var, returnType, discriminant, true, false}) =
+prettyPrec d (If {returnType, discriminant, true, false}) =
prettyApp d (pretty "if") $
- [ prettyLambda App var.val (prettyPrecBounds Open returnType)
+ [ prettyPrecLambda App returnType
, prettyPrecBounds App discriminant
, prettyPrecBounds App true
, prettyPrecBounds App false
diff --git a/src/Obs/Typing.idr b/src/Obs/Typing.idr
index b3762cf..c3dcfbf 100644
--- a/src/Obs/Typing.idr
+++ b/src/Obs/Typing.idr
@@ -1,6 +1,6 @@
module Obs.Typing
-import Control.Monad.Maybe
+import Control.Monad.Identity
import Data.Nat
@@ -38,90 +38,99 @@ universeMismatch lhs rhs = inScope "universe mismatch" $ mismatch lhs rhs
-- Utilities -------------------------------------------------------------------
-MkPair : (s, s' : Universe)
- -> NormalForm (relevance s) ctx
- -> NormalForm (relevance s') ctx
- -> NormalForm (relevance (max s s')) ctx
-MkPair Prop Prop t u = u
-MkPair Prop s'@(Set _) t u = Cnstr $ Pair Prop s' Set t u
-MkPair s@(Set _) s' t u = Cnstr $ Pair s s' Set t u
+MkPair : (indexRel, elementRel : Relevance)
+ -> (first : NormalForm indexRel ctx)
+ -> (second : NormalForm elementRel ctx)
+ -> NormalForm (pair indexRel elementRel) ctx
+MkPair Irrelevant Irrelevant first second = Irrel
+MkPair Irrelevant Relevant first second =
+ Cnstr $ Pair {indexRel = Irrelevant, elementRel = Relevant, prf = Relevant, first, second}
+MkPair Relevant elementRel first second =
+ Cnstr $ Pair {indexRel = Relevant, elementRel, prf = Relevant, first, second}
-- Checking and Inference ------------------------------------------------------
check' : (tyCtx : TyContext ctx)
- -> (s : Universe)
- -> TypeNormalForm ctx
- -> Term (length ctx)
- -> Logging ann (NormalForm (relevance s) ctx)
+ -> (sort : Universe)
+ -> (type : TypeNormalForm ctx)
+ -> (term : Term (length ctx))
+ -> Logging ann (NormalForm (relevance sort) ctx)
infer' : (tyCtx : TyContext ctx)
- -> Term (length ctx)
- -> Logging ann (s ** (TypeNormalForm ctx, NormalForm (relevance s) ctx))
+ -> (term : Term (length ctx))
+ -> Logging ann (sort : Universe ** (TypeNormalForm ctx, NormalForm (relevance sort) ctx))
-inferType' : {default typeMismatch tag : forall a . Doc ann -> Doc ann -> Logging ann a}
+inferType' : {default typeMismatch tag : forall a . (expected, actual : Doc ann) -> Logging ann a}
-> (tyCtx : TyContext ctx)
- -> Term (length ctx)
+ -> (term : Term (length ctx))
-> Logging ann (Universe, TypeNormalForm ctx)
-inferType' ctx t = do
- (Set _ ** (Cnstr (Universe s), a)) <- infer' ctx t
- | (_ ** (type, a)) => tag (pretty "sort") (pretty type)
- pure (s, a)
+inferType' ctx term = do
+ (Set _ ** (Cnstr (Universe sort), type)) <- infer' ctx term
+ | (_ ** (type, term)) => tag (pretty "sort") (pretty type)
+ pure (sort, type)
check : (tyCtx : TyContext ctx)
- -> (s : Universe)
- -> TypeNormalForm ctx
- -> WithBounds (Term (length ctx))
- -> Logging ann (NormalForm (relevance s) ctx)
-check ctx s a (MkBounded t irrel bounds) = inBounds (MkBounded (check' ctx s a t) irrel bounds)
+ -> (sort : Universe)
+ -> (type : TypeNormalForm ctx)
+ -> (term : WithBounds (Term (length ctx)))
+ -> Logging ann (NormalForm (relevance sort) ctx)
+check ctx sort type (MkBounded term irrel bounds) =
+ inBounds (MkBounded (check' ctx sort type term) irrel bounds)
checkType : (tyCtx : TyContext ctx)
- -> (s : Universe)
- -> WithBounds (Term (length ctx))
+ -> (sort : Universe)
+ -> (term : WithBounds (Term (length ctx)))
-> Logging ann (TypeNormalForm ctx)
-checkType ctx s tm = check ctx (succ s) (cast s) tm
+checkType ctx sort term = check ctx (succ sort) (cast sort) term
infer : (tyCtx : TyContext ctx)
- -> WithBounds (Term (length ctx))
- -> Logging ann (s ** (TypeNormalForm ctx, NormalForm (relevance s) ctx))
-infer ctx (MkBounded t irrel bounds) = inBounds (MkBounded (infer' ctx t) irrel bounds)
+ -> (term : WithBounds (Term (length ctx)))
+ -> Logging ann (sort : Universe ** (TypeNormalForm ctx, NormalForm (relevance sort) ctx))
+infer ctx (MkBounded term irrel bounds) = inBounds (MkBounded (infer' ctx term) irrel bounds)
inferType : {default typeMismatch tag : forall a . Doc ann -> Doc ann -> Logging ann a}
-> (tyCtx : TyContext ctx)
- -> WithBounds (Term (length ctx))
+ -> (term : WithBounds (Term (length ctx)))
-> Logging ann (Universe, TypeNormalForm ctx)
-inferType ctx (MkBounded t irrel bounds) = inBounds (MkBounded (inferType' ctx t) irrel bounds)
+inferType ctx (MkBounded term irrel bounds) =
+ inBounds (MkBounded (inferType' ctx term) irrel bounds)
-check' ctx sort (Cnstr (Pi domainSort codomainSort _ domain codomain)) (Lambda {var, body}) = do
+check' ctx sort
+ (Cnstr (Pi {domainSort, codomainSort, domain, codomain}))
+ (Lambda {body = MkLambda var body}) = do
info "encountered lambda"
let Yes Refl = decEq sort (domainSort ~> codomainSort)
| No _ => fatal "internal universe mismatch"
- let bodyCtx = ctx ::< MkFreeVar domainSort domain var.val
+ let bodyCtx = ctx ::< MkFreeVar domainSort domain.type var.val
trace $ pretty {ann} "checking body has type" <++> pretty codomainSort
body <- check bodyCtx codomainSort codomain body
pure $ case codomainSort of
Prop => Irrel
- Set _ => Cnstr (Lambda domainSort var.val body)
+ Set _ => Cnstr (Lambda {domainRel = _, var = Just var.val, body})
-check' ctx sort type (Lambda {var, body}) = typeMismatch (pretty "function") (pretty type)
+check' ctx sort type (Lambda {body}) = typeMismatch (pretty "function") (pretty type)
-check' ctx sort (Cnstr (Sigma indexSort elementSort var index element)) (Pair {first, second}) = do
+check' ctx sort
+ (Cnstr (Sigma {indexSort, elementSort, index, element}))
+ (Pair {first, second}) = do
info "encountered pair"
let Yes Refl = decEq sort (max indexSort elementSort)
| No _ => fatal "internal universe mismatch"
+ rewrite pairRelevance indexSort elementSort
- trace $ pretty {ann} "checking first has type" <++> pretty index
- first <- check ctx indexSort index first
+ trace $ pretty {ann} "checking first has type" <++> pretty index.type
+ first <- check ctx indexSort index.type first
element <- subst1 first element
trace $ pretty {ann} "checking second has type" <++> pretty element
second <- check ctx elementSort element second
- pure $ MkPair indexSort elementSort first second
+ pure $ MkPair {indexRel = _, elementRel = _, first, second}
check' ctx sort type (Pair {first, second}) = typeMismatch (pretty "pair type") (pretty type)
@@ -145,8 +154,8 @@ check' ctx sort type t = do
expandedType <- subst type (reduce ctx)
expandedInferredType <- subst inferredType (reduce ctx)
- Just _ <- inScope "convert" $ runMaybeT $ convert (succ sort) (cast sort) expandedType expandedInferredType
- | Nothing => inScope "conversion failed" $ mismatch (pretty type) (pretty inferredType)
+ let True = runIdentity $ convert Relevant (cast sort) expandedType expandedInferredType
+ | False => inScope "conversion failed" $ mismatch (pretty type) (pretty inferredType)
pure value
@@ -162,7 +171,7 @@ infer' ctx (Universe {s}) = do
pure (succ (succ s) ** (cast (succ s), cast s))
-infer' ctx (Pi {var, domain, codomain}) = do
+infer' ctx (Pi {domain = MkDecl var domain, codomain}) = do
info "encountered pi"
(domainSort, domain) <- inferType ctx domain
@@ -175,10 +184,15 @@ infer' ctx (Pi {var, domain, codomain}) = do
trace $ pretty {ann} "codomain type is" <++> pretty codomain
let piSort = domainVar.sort ~> codomainSort
- let term = Cnstr (Pi domainVar.sort codomainSort var.val domain codomain)
+ let term = Cnstr $ Pi
+ { domainSort = domainVar.sort
+ , codomainSort
+ , domain = MkDecl (Just var.val) domain
+ , codomain
+ }
pure (succ piSort ** (cast piSort, term))
-infer' ctx (Lambda {var, body}) = fatal "cannot infer type of lambda"
+infer' ctx (Lambda {body}) = fatal "cannot infer type of lambda"
infer' ctx (App {fun, arg}) = do
info "encountered application"
@@ -186,7 +200,7 @@ infer' ctx (App {fun, arg}) = do
(piSort ** (funType, funValue)) <- infer ctx fun
trace $ pretty {ann} "function has type" <++> pretty funType
- let Cnstr (Pi domainSort codomainSort _ domain codomain) = funType
+ let Cnstr (Pi {domainSort, codomainSort, domain, codomain}) = funType
| _ => inBounds $ map (const $ typeMismatch (pretty "function") (pretty funType)) fun
let Yes Refl = decEq piSort (domainSort ~> codomainSort)
@@ -194,8 +208,8 @@ infer' ctx (App {fun, arg}) = do
let fun = funValue
- trace $ pretty {ann} "checking argument has type" <++> pretty domain
- arg <- check ctx domainSort domain arg
+ trace $ pretty {ann} "checking argument has type" <++> pretty domain.type
+ arg <- check ctx domainSort domain.type arg
trace $ pretty {ann} "argument is well typed"
returnType <- subst1 arg codomain
@@ -205,7 +219,7 @@ infer' ctx (App {fun, arg}) = do
pure (codomainSort ** (returnType, returnValue))
-infer' ctx (Sigma {var, index, element}) = do
+infer' ctx (Sigma {index = MkDecl var index, element}) = do
info "encountered sigma"
(indexSort, index) <- inferType ctx index
@@ -218,7 +232,12 @@ infer' ctx (Sigma {var, index, element}) = do
trace $ pretty {ann} "element type is" <++> pretty element
let sigmaSort = max indexVar.sort elementSort
- let term = Cnstr (Sigma indexVar.sort elementSort var.val index element)
+ let term = Cnstr $ Sigma
+ { indexSort = indexVar.sort
+ , elementSort
+ , index = MkDecl (Just var.val) index
+ , element
+ }
pure (succ sigmaSort ** (cast sigmaSort, term))
infer' ctx (Pair {first, second}) = fatal "cannot infer type of pair"
@@ -229,7 +248,7 @@ infer' ctx (First {arg}) = do
(sigmaSort ** (argType, argValue)) <- infer ctx arg
trace $ pretty {ann} "pair has type" <++> pretty argType
- let Cnstr (Sigma indexSort elementSort _ index element) = argType
+ let Cnstr (Sigma {indexSort, elementSort, index, element}) = argType
| _ => inBounds $ map (const $ typeMismatch (pretty "pair type") (pretty argType)) arg
let Yes Refl = decEq sigmaSort (max indexSort elementSort)
@@ -237,7 +256,7 @@ infer' ctx (First {arg}) = do
let argValue = rewrite sym $ pairRelevance indexSort elementSort in argValue
- let returnType = index
+ let returnType = index.type
returnValue <- doFst (relevance indexSort) (relevance elementSort) argValue
pure (indexSort ** (returnType, returnValue))
@@ -248,7 +267,7 @@ infer' ctx (Second {arg}) = do
(sigmaSort ** (argType, argValue)) <- infer ctx arg
trace $ pretty {ann} "pair has type" <++> pretty argType
- let Cnstr (Sigma indexSort elementSort _ index element) = argType
+ let Cnstr (Sigma {indexSort, elementSort, index, element}) = argType
| _ => inBounds $ map (const $ typeMismatch (pretty "pair type") (pretty argType)) arg
let Yes Refl = decEq sigmaSort (max indexSort elementSort)
@@ -274,7 +293,7 @@ infer' ctx False = do
info "encountered false"
pure (Set 0 ** (Cnstr Bool, Cnstr False))
-infer' ctx (If {var, returnType, discriminant, true, false}) = do
+infer' ctx (If {returnType = MkLambda var returnType, discriminant, true, false}) = do
info "encountered if"
trace "checking discriminant is bool"
@@ -348,7 +367,12 @@ infer' ctx (Transp {indexedType, oldIndex, value, newIndex, equality}) = do
newIndex <- check ctx indexSort indexType newIndex
trace "new index is well typed"
- let indexedTypeShape = Cnstr $ Pi indexSort (Set 0) "" indexType (Cnstr (Universe Prop))
+ let indexedTypeShape = Cnstr $ Pi
+ { domainSort = indexSort
+ , codomainSort = Set 0
+ , domain = MkDecl Nothing indexType
+ , codomain = Cnstr (Universe Prop)
+ }
indexedType <- check ctx (indexSort ~> Set 0) indexedTypeShape indexedType
trace $ pretty {ann} "result is an index of type" <++> pretty indexedType
diff --git a/src/Obs/Typing/Context.idr b/src/Obs/Typing/Context.idr
index 4706dca..ad1d0a7 100644
--- a/src/Obs/Typing/Context.idr
+++ b/src/Obs/Typing/Context.idr
@@ -64,7 +64,7 @@ fromVar var = MkDefinition
{ name = var.name
, sort = var.sort
, ty = weaken [relevance var.sort] var.ty
- , tm = point (var.name, (var.sort ** Refl)) Here
+ , tm = point (Just var.name) Here
, correct = Refl
}
@@ -104,5 +104,5 @@ reduce : (tyCtx : TyContext ctx) -> Map ctx (LogNormalForm ann) (freeVars tyCtx)
reduce [] = absurd
reduce (ctx :< def) = add (LogNormalForm ann) (subst def.tm (reduce ctx)) (reduce ctx)
reduce (ctx ::< var) = add (LogNormalForm ann)
- (pure $ point (var.name, (var.sort ** Refl)) Here)
+ (pure $ point (Just var.name) Here)
(\i => pure $ weaken [_] $ !(reduce ctx i))
diff --git a/src/Obs/Typing/Conversion.idr b/src/Obs/Typing/Conversion.idr
index 766c21e..93812c1 100644
--- a/src/Obs/Typing/Conversion.idr
+++ b/src/Obs/Typing/Conversion.idr
@@ -1,7 +1,6 @@
module Obs.Typing.Conversion
-import Control.Monad.Maybe
-import Control.Monad.Trans
+import Control.Monad.Identity
import Data.Bool
import Data.Nat
@@ -18,190 +17,193 @@ import Obs.Universe
-- Conversion ------------------------------------------------------------------
+convertUntyped : (rel : Relevance) -> (left, right : NormalForm rel ctx) -> Identity Bool
+
export
-convert : (s : Universe)
- -> (a : TypeNormalForm ctx)
- -> (t, u : NormalForm (relevance s) ctx)
- -> MaybeT (Logging ann) (NormalForm (relevance s) ctx)
-
-untypedConvert : (t, u : NormalForm Relevant ctx) -> MaybeT (Logging ann) (NormalForm Relevant ctx)
--- Diagonals
-untypedConvert (Cnstr (Universe s)) (Cnstr (Universe s')) =
- if s == s' then pure (Cnstr (Universe s)) else nothing
-untypedConvert (Cnstr (Pi s s' var a b)) (Cnstr (Pi l l' _ a' b')) = do
- let Yes Refl = decEq s l
- | No _ => nothing
- lift $ trace "going back to type-directed conversion"
- a <- assert_total (convert (succ s) (cast s) a a')
- b <- assert_total (convert (succ s') (cast s') b b')
- pure (Cnstr $ Pi s s' var a b)
-untypedConvert (Cnstr (Lambda s var t)) (Cnstr (Lambda s' _ u)) = do
- let Yes Refl = decEq s s'
- | No _ => nothing
- lift $ trace "converting under lambda"
- t <- untypedConvert t u
- pure (Cnstr $ Lambda s var t)
-untypedConvert (Cnstr (Sigma s s' var a b)) (Cnstr (Sigma l l' _ a' b')) = do
- let Yes Refl = decEq s l
- | No _ => nothing
- lift $ trace "going back to type-directed conversion"
- a <- assert_total (convert (succ s) (cast s) a a')
- b <- assert_total (convert (succ s') (cast s') b b')
- pure (Cnstr $ Sigma s s' var a b)
-untypedConvert (Cnstr (Pair s@(Set _) s'@(Set _) prf t u)) (Cnstr (Pair l l' prf' t' u')) = do
- let Yes Refl = decEq (s, s') (l, l')
- | No _ => nothing
- lift $ trace "converting pair pointwise"
- t <- untypedConvert t t'
- u <- untypedConvert u u'
- pure (Cnstr $ Pair l l' Set t u)
-untypedConvert (Cnstr (Pair s@(Set _) Prop prf t u)) (Cnstr (Pair l Prop prf' t' u')) = do
- let Yes Refl = decEq s l
- | No _ => nothing
- lift $ trace "converting pair pointwise"
- t <- untypedConvert t t'
- pure (Cnstr $ Pair l Prop Set t Irrel)
-untypedConvert (Cnstr (Pair Prop s'@(Set _) prf t u)) (Cnstr (Pair Prop l' prf' t' u')) = do
- let Yes Refl = decEq s' l'
- | No _ => nothing
- lift $ trace "converting pair pointwise"
- u <- untypedConvert u u'
- pure (Cnstr $ Pair Prop l' Set Irrel u)
-untypedConvert (Cnstr Bool) (Cnstr Bool) = pure (Cnstr Bool)
-untypedConvert (Cnstr True) (Cnstr True) = pure (Cnstr True)
-untypedConvert (Cnstr False) (Cnstr False) = pure (Cnstr False)
-untypedConvert (Cnstr Top) (Cnstr Top) = pure (Cnstr Top)
-untypedConvert (Cnstr Bottom) (Cnstr Bottom) = pure (Cnstr Bottom)
-untypedConvert t@(Ntrl (Var _ _ _ i)) (Ntrl (Var _ _ _ j)) =
- if elemToNat i == elemToNat j then pure t else nothing
-untypedConvert lhs@(Ntrl (App r t u)) rhs@(Ntrl (App r' t' u')) = do
- let Yes Refl = decEq r r'
- | No _ => nothing
- lift $ trace "checking parts of a spine"
- t <- untypedConvert (assert_smaller lhs (Ntrl t)) (assert_smaller rhs (Ntrl t'))
- let Relevant = r'
- | Irrelevant => lift $ doApp t Irrel
- u <- untypedConvert u u'
- lift $ doApp t u
-untypedConvert lhs@(Ntrl (Fst r t)) rhs@(Ntrl (Fst r' t')) = do
- lift $ trace "checking full pair for fst"
- t <- untypedConvert (assert_smaller lhs (Ntrl t)) (assert_smaller rhs (Ntrl t'))
- lift $ doFst Relevant r t
-untypedConvert lhs@(Ntrl (Snd r t)) rhs@(Ntrl (Snd r' t')) = do
- lift $ trace "checking full pair for snd"
- t <- untypedConvert (assert_smaller lhs (Ntrl t)) (assert_smaller rhs (Ntrl t'))
- lift $ doSnd r Relevant (rewrite pairRelevantRight r in t)
-untypedConvert lhs@(Ntrl (If t f g)) rhs@(Ntrl (If t' f' g')) = do
- lift $ trace "checking all branches of if"
- t <- untypedConvert (assert_smaller lhs (Ntrl t)) (assert_smaller rhs (Ntrl t'))
- f <- untypedConvert f f'
- g <- untypedConvert g g'
- lift $ doIf t f g
-untypedConvert (Ntrl Absurd) (Ntrl Absurd) = pure (Ntrl Absurd)
-untypedConvert lhs@(Ntrl (Equal a t u)) rhs@(Ntrl (Equal a' t' u')) = do
- lift $ trace "checking equal (stuck on type)"
- a <- untypedConvert (assert_smaller lhs (Ntrl a)) (assert_smaller rhs (Ntrl a'))
- t <- untypedConvert t t'
- u <- untypedConvert u u'
- lift $ doEqual _ a t u
-untypedConvert lhs@(Ntrl (EqualL t u)) rhs@(Ntrl (EqualL t' u')) = do
- lift $ trace "checking equal (stuck on left)"
- t <- untypedConvert (assert_smaller lhs (Ntrl t)) (assert_smaller rhs (Ntrl t'))
- u <- untypedConvert u u'
- lift $ doEqualSet t u
-untypedConvert lhs@(Ntrl (EqualR t u)) rhs@(Ntrl (EqualR t' u')) = do
- lift $ trace "checking equal (stuck on right)"
- t <- untypedConvert (assert_smaller lhs (Cnstr t)) (assert_smaller rhs (Cnstr t'))
- u <- untypedConvert (assert_smaller lhs (Ntrl u)) (assert_smaller rhs (Ntrl u'))
- lift $ doEqualSet t u
-untypedConvert lhs@(Ntrl (EqualStuck t u)) rhs@(Ntrl (EqualStuck t' u')) = do
- lift $ trace "checking equal (head mismatch)"
- t <- untypedConvert (assert_smaller lhs (Cnstr t)) (assert_smaller rhs (Cnstr t'))
- u <- untypedConvert (assert_smaller lhs (Cnstr u)) (assert_smaller rhs (Cnstr u'))
- lift $ doEqualSet t u
-untypedConvert lhs@(Ntrl (CastL a b t)) rhs@(Ntrl (CastL a' b' t')) = do
- lift $ trace "checking cast (stuck on left)"
- a <- untypedConvert (assert_smaller lhs (Ntrl a)) (assert_smaller rhs (Ntrl a'))
- b <- untypedConvert b b'
- t <- untypedConvert t t'
- lift $ doCast _ a b t
-untypedConvert lhs@(Ntrl (CastR a b t)) rhs@(Ntrl (CastR a' b' t')) = do
- lift $ trace "checking cast (stuck on right)"
- a <- untypedConvert (assert_smaller lhs (Cnstr a)) (assert_smaller rhs (Cnstr a'))
- b <- untypedConvert (assert_smaller lhs (Ntrl b)) (assert_smaller rhs (Ntrl b'))
- t <- untypedConvert t t'
- lift $ doCast _ a b t
-untypedConvert lhs@(Ntrl (CastStuck a b t)) rhs@(Ntrl (CastStuck a' b' t')) = do
- lift $ trace "checking cast (stuck on left)"
- a <- untypedConvert (assert_smaller lhs (Cnstr a)) (assert_smaller rhs (Cnstr a'))
- b <- untypedConvert (assert_smaller lhs (Cnstr b)) (assert_smaller rhs (Cnstr b'))
- t <- untypedConvert t t'
- lift $ doCast _ a b t
--- Pi types
-untypedConvert t@(Cnstr (Lambda s var _)) (Ntrl u) = do
- u <- lift $ doApp (Ntrl $ weaken [relevance s] u) (point (var, (s ** Refl)) Here)
- assert_total (untypedConvert t (Cnstr (Lambda s var u)))
-untypedConvert (Ntrl t) u@(Cnstr (Lambda s var _)) = do
- t <- lift $ doApp (Ntrl $ weaken [relevance s] t) (point (var, (s ** Refl)) Here)
- assert_total (untypedConvert (Cnstr (Lambda s var t)) u)
--- Sigma types
-untypedConvert t@(Cnstr (Pair s s' prf _ _)) t'@(Ntrl _) =
- let t'' : NormalForm (pair (relevance s) (relevance s')) ctx
- t'' = rewrite trans (sym $ pairRelevance s s') (forgetIsRelevant prf) in t'
- in do
- t' <- lift $ doFst (relevance s) (relevance s') t''
- u' <- lift $ doSnd (relevance s) (relevance s') t''
- assert_total (untypedConvert t (Cnstr (Pair s s' prf t' u')))
-untypedConvert t@(Ntrl _) t'@(Cnstr (Pair s s' prf _ _)) =
- let t'' : NormalForm (pair (relevance s) (relevance s')) ctx
- t'' = rewrite trans (sym $ pairRelevance s s') (forgetIsRelevant prf) in t
- in do
- t <- lift $ doFst (relevance s) (relevance s') t''
- u <- lift $ doSnd (relevance s) (relevance s') t''
- assert_total (untypedConvert (Cnstr (Pair s s' prf t u)) t')
--- Bools
--- no cases because diagonals complete
--- Fallback
-untypedConvert _ _ = nothing
-
-convert Prop a Irrel Irrel = pure Irrel
-convert (Set k) (Ntrl a) t u = do
- lift $ trace $ pretty {ann} "cannot do type-directed conversion on" <++> pretty a
- untypedConvert t u
-convert (Set k) (Cnstr (Universe s)) t u = do
- lift $ trace $ pretty {ann} "converting in type" <++> pretty s
- untypedConvert t u
-convert (Set k) (Cnstr (Pi s s'@(Set _) var a b)) t u = do
- -- s' must be Set, otherwise ty is in Prop
- lift $ trace "converting pi type"
- t' <- lift $ doApp (Sorted.weaken [relevance s] t) (point (var, (s ** Refl)) Here)
- u' <- lift $ doApp (Sorted.weaken [relevance s] u) (point (var, (s ** Refl)) Here)
- t <- convert s' b t' u'
- pure (Cnstr $ Lambda s var t)
-convert (Set k) ty@(Cnstr (Sigma s@(Set j) s' var a b)) t u = do
- lift $ trace "converting sigma type"
- t1 <- lift $ doFst Relevant (relevance s') t
- u1 <- lift $ doFst Relevant (relevance s') u
- t1 <- convert s a t1 u1
- t2 <- lift $ doSnd Relevant (relevance s') t
- u2 <- lift $ doSnd Relevant (relevance s') u
- b <- lift $ subst1 t1 b
- t2 <- convert s' (assert_smaller ty b) t2 u2
- pure (Cnstr $ Pair s s' Set t1 t2)
-convert (Set k) ty@(Cnstr (Sigma Prop s'@(Set _) var a b)) t u = do
- lift $ trace "converting sigma type (snd only)"
- t2 <- lift $ doSnd Irrelevant Relevant t
- u2 <- lift $ doSnd Irrelevant Relevant u
- b <- lift $ subst1 Irrel b
- t2 <- convert s' (assert_smaller ty b) t2 u2
- pure (Cnstr $ Pair Prop s' Set Irrel t2)
-convert (Set 0) (Cnstr Bool) (Cnstr True) (Cnstr True) = do
- lift $ trace "converting bool (true)"
- pure (Cnstr True)
-convert (Set 0) (Cnstr Bool) (Cnstr False) (Cnstr False) = do
- lift $ trace "converting bool (false)"
- pure (Cnstr False)
-convert (Set k) (Cnstr Bool) t@(Ntrl _) u@(Ntrl _) = do
- lift $ trace "converting bool (neutral)"
- untypedConvert t u
-convert (Set k) (Cnstr a) t u = lift $ inScope "bad type constructor" $ fatal a
+convert : (rel : Relevance)
+ -> (type : TypeNormalForm ctx)
+ -> (left, right : NormalForm rel ctx)
+ -> Identity Bool
+convert rel type left right = convertUntyped rel left right
+
+convertCnstr : (left, right : Constructor ctx) -> Identity Bool
+convertCnstr (Universe {s}) (Universe {s = s'}) = pure (s == s')
+convertCnstr
+ (Pi {domainSort, codomainSort, domain, codomain})
+ (Pi
+ { domainSort = domainSort'
+ , codomainSort = codomainSort'
+ , domain = domain'
+ , codomain = codomain'
+ }) = do
+ let Yes Refl = decEq (domainSort, codomainSort) (domainSort', codomainSort')
+ | No _ => pure False
+
+ convertDomain <- convert
+ { rel = Relevant
+ , type = cast domainSort
+ , left = assert_smaller domain domain.type
+ , right = assert_smaller domain' domain'.type
+ }
+
+ convertCodomain <- convert
+ { rel = Relevant
+ , type = cast codomainSort
+ , left = codomain
+ , right = codomain'
+ }
+
+ pure (convertDomain && convertCodomain)
+convertCnstr
+ (Lambda {domainRel, var = _, body})
+ (Lambda {domainRel = domainRel', var = _, body = body'}) = do
+ let Yes Refl = decEq domainRel domainRel'
+ | No _ => pure False
+
+ convertUntyped {rel = Relevant, left = body, right = body'}
+convertCnstr
+ (Sigma {indexSort, elementSort, index, element})
+ (Sigma
+ { indexSort = indexSort'
+ , elementSort = elementSort'
+ , index = index'
+ , element = element'
+ }) = do
+ let Yes Refl = decEq (indexSort, elementSort) (indexSort', elementSort')
+ | No _ => pure False
+
+ convertIndex <- convert
+ { rel = Relevant
+ , type = cast indexSort
+ , left = assert_smaller index index.type
+ , right = assert_smaller index' index'.type
+ }
+
+ convertElement <- convert
+ { rel = Relevant
+ , type = cast elementSort
+ , left = element
+ , right = element'
+ }
+
+ pure (convertIndex && convertElement)
+convertCnstr
+ left@(Pair {indexRel, elementRel, prf = _, first, second})
+ right@(Pair
+ { indexRel = indexRel'
+ , elementRel = elementRel'
+ , prf = _
+ , first = first'
+ , second = second'
+ }) = do
+ let Yes Refl = decEq (indexRel, elementRel) (indexRel', elementRel')
+ | No _ => pure False
+
+ convertFirst <- convertUntyped {rel = indexRel, left = first, right = first'}
+ convertSecond <- convertUntyped {rel = elementRel, left = second, right = second'}
+ pure (convertFirst && convertSecond)
+convertCnstr Bool Bool = pure True
+convertCnstr True True = pure True
+convertCnstr False False = pure True
+convertCnstr Top Top = pure True
+convertCnstr Bottom Bottom = pure True
+convertCnstr left right = pure False
+
+convertNtrl : (left, right : Neutral ctx) -> Identity Bool
+convertNtrl (Var {var = _, i}) (Var {var = _, i = j}) = pure (elemToNat i == elemToNat j)
+convertNtrl (App {argRel, fun, arg}) (App {argRel = argRel', fun = fun', arg = arg'}) = do
+ let Yes Refl = decEq argRel argRel'
+ | No _ => pure False
+
+ convertFun <- convertNtrl {left = fun, right = fun'}
+ convertArg <- convertUntyped {rel = argRel, left = arg, right = arg'}
+ pure (convertFun && convertArg)
+convertNtrl (First {secondRel = _, arg}) (First {secondRel = _, arg = arg'}) =
+ convertNtrl arg arg'
+convertNtrl (Second {firstRel = _, arg}) (Second {firstRel = _, arg = arg'}) =
+ convertNtrl arg arg'
+convertNtrl
+ (If {discriminant, true, false})
+ (If {discriminant = discriminant', true = true', false = false'}) =
+ do
+ convertDiscriminant <- convertNtrl {left = discriminant, right = discriminant}
+ convertTrue <- convertUntyped {rel = Relevant, left = true, right = true'}
+ convertFalse <- convertUntyped {rel = Relevant, left = false, right = false'}
+ pure (convertDiscriminant && convertTrue && convertFalse)
+convertNtrl Absurd Absurd = pure True
+convertNtrl
+ (Equal {type, left, right})
+ (Equal {type = type', left = left', right = right'}) =
+ do
+ convertType <- convertNtrl {left = type, right = type'}
+ convertLeft <- convertUntyped {rel = Relevant, left = left, right = left'}
+ convertRight <- convertUntyped {rel = Relevant, left = right, right = right'}
+ pure (convertType && convertLeft && convertRight)
+-- We don't need to check, e.g. EqualL and EqualR
+-- Assume (EqualL left right) ~~ (EqualR left' right')
+-- Then (Ntrl left) ~~ (Cnstr left')
+-- This means left' is either Lambda or Pair
+-- Lamda and Pair are not type constructors.
+-- Hence we have a contradiction, so we are done.
+convertNtrl (EqualL {left, right}) (EqualL {left = left', right = right'}) = do
+ convertLeft <- convertNtrl {left = left, right = left'}
+ convertRight <- convertUntyped {rel = Relevant, left = right, right = right'}
+ pure (convertLeft && convertRight)
+convertNtrl (EqualR {left, right}) (EqualR {left = left', right = right'}) = do
+ convertLeft <- convertCnstr {left = left, right = left'}
+ convertRight <- convertNtrl {left = right, right = right'}
+ pure (convertLeft && convertRight)
+convertNtrl (EqualStuck {left, right}) (EqualStuck {left = left', right = right'}) = do
+ convertLeft <- convertCnstr {left = left, right = left'}
+ convertRight <- convertCnstr {left = right, right = right'}
+ pure (convertLeft && convertRight)
+convertNtrl
+ (CastL {oldType, newType, value})
+ (CastL {oldType = oldType', newType = newType', value = value'}) =
+ do
+ convertOldType <- convertNtrl {left = oldType, right = oldType'}
+ convertNewType <- convertUntyped {rel = Relevant, left = newType, right = newType'}
+ convertValue <- convertUntyped {rel = Relevant, left = value, right = value'}
+ pure (convertOldType && convertNewType && convertValue)
+convertNtrl
+ (CastR {oldType, newType, value})
+ (CastR {oldType = oldType', newType = newType', value = value'}) =
+ do
+ convertOldType <- convertCnstr {left = oldType, right = oldType'}
+ convertNewType <- convertNtrl {left = newType, right = newType'}
+ convertValue <- convertUntyped {rel = Relevant, left = value, right = value'}
+ pure (convertOldType && convertNewType && convertValue)
+convertNtrl
+ (CastStuck {oldType, newType, value})
+ (CastStuck {oldType = oldType', newType = newType', value = value'}) =
+ do
+ convertOldType <- convertCnstr {left = oldType, right = oldType'}
+ convertNewType <- convertCnstr {left = newType, right = newType'}
+ convertValue <- convertUntyped {rel = Relevant, left = value, right = value'}
+ pure (convertOldType && convertNewType && convertValue)
+convertNtrl left right = pure False
+
+convertEta : (left : Constructor ctx) -> (right : Neutral ctx) -> Identity Bool
+convertEta (Lambda {domainRel, var, body}) right = do
+ let right = weaken [domainRel] right
+ let rightBody = App {argRel = domainRel, fun = right, arg = point Nothing Here}
+ convertUntyped {rel = Relevant, left = body, right = Ntrl rightBody}
+convertEta (Pair {indexRel = Relevant, elementRel = Relevant, prf, first, second}) right = do
+ let rightFirst = First {secondRel = Relevant, arg = right}
+ let rightSecond = Second {firstRel = Relevant, arg = right}
+ convertFirst <- convertUntyped {rel = Relevant, left = first, right = Ntrl rightFirst}
+ convertSecond <- convertUntyped {rel = Relevant, left = second, right = Ntrl rightSecond}
+ pure (convertFirst && convertSecond)
+convertEta (Pair {indexRel = Relevant, elementRel = Irrelevant, prf, first, second}) right = do
+ let rightFirst = First {secondRel = Relevant, arg = right}
+ convertUntyped {rel = Relevant, left = first, right = Ntrl rightFirst}
+convertEta (Pair {indexRel = Irrelevant, elementRel = Relevant, prf, first, second}) right = do
+ let rightSecond = Second {firstRel = Relevant, arg = right}
+ convertUntyped {rel = Relevant, left = second, right = Ntrl rightSecond}
+convertEta left right = pure False
+
+convertUntyped Irrelevant left right = pure True
+convertUntyped Relevant (Ntrl left) (Ntrl right) = convertNtrl left right
+convertUntyped Relevant (Ntrl left) (Cnstr right) = assert_total (convertEta right left)
+convertUntyped Relevant (Cnstr left) (Ntrl right) = convertEta left right
+convertUntyped Relevant (Cnstr left) (Cnstr right) = convertCnstr left right
diff --git a/src/Obs/Universe.idr b/src/Obs/Universe.idr
index 1517c4c..14cde14 100644
--- a/src/Obs/Universe.idr
+++ b/src/Obs/Universe.idr
@@ -127,16 +127,6 @@ relevance : Universe -> Relevance
relevance Prop = Irrelevant
relevance (Set k) = Relevant
-||| True if values in `s` are proof-irrelevant.
-public export
-isIrrelevant : (s : Universe) -> Bool
-isIrrelevant = (Irrelevant ==) . relevance
-
-||| True if values in `s` are proof-relevant.
-public export
-isRelevant : (s : Universe) -> Bool
-isRelevant = (Relevant ==) . relevance
-
||| Returns the smallest universe containing `s`
||| @ s the universe to contain
public export
@@ -155,30 +145,30 @@ dom ~> (Set k) = max (Set k) dom
namespace Predicates
public export
- data IsIrrelevant : Universe -> Type where
- Prop : IsIrrelevant Prop
+ data IsIrrelevant : Relevance -> Type where
+ Irrelevant : IsIrrelevant Irrelevant
public export
- data IsRelevant : Universe -> Type where
- Set : IsRelevant (Set k)
+ data IsRelevant : Relevance -> Type where
+ Relevant : IsRelevant Relevant
export
- Uninhabited (IsIrrelevant (Set k)) where
+ Uninhabited (IsIrrelevant Relevant) where
uninhabited _ impossible
export
- Uninhabited (IsRelevant Prop) where
+ Uninhabited (IsRelevant Irrelevant) where
uninhabited _ impossible
export
- isIrrelevant : (s : Universe) -> Dec (IsIrrelevant s)
- isIrrelevant Prop = Yes Prop
- isIrrelevant (Set k) = No absurd
+ isIrrelevant : (r : Relevance) -> Dec (IsIrrelevant r)
+ isIrrelevant Irrelevant = Yes Irrelevant
+ isIrrelevant Relevant = No absurd
export
- isRelevant : (s : Universe) -> Dec (IsRelevant s)
- isRelevant Prop = No absurd
- isRelevant (Set k) = Yes Set
+ isRelevant : (r : Relevance) -> Dec (IsRelevant r)
+ isRelevant Irrelevant = No absurd
+ isRelevant Relevant = Yes Relevant
-- Properties ------------------------------------------------------------------
@@ -194,22 +184,6 @@ succContains (Set k) = eqToSo $ LteIslte k k reflexive
succLeast : (s, s' : Universe) -> So (s < s') -> So (succ s <= s')
succLeast s s' prf = prf
-irrelevantReflection : (s : Universe) -> Reflects (IsIrrelevant s) (isIrrelevant s)
-irrelevantReflection Prop = RTrue Prop
-irrelevantReflection (Set k) = RFalse absurd
-
-relevantReflection : (s : Universe) -> Reflects (IsRelevant s) (isRelevant s)
-relevantReflection Prop = RFalse absurd
-relevantReflection (Set k) = RTrue Set
-
-export
-forgetIsIrrelevant : IsIrrelevant s -> relevance s = Irrelevant
-forgetIsIrrelevant Prop = Refl
-
-export
-forgetIsRelevant : IsRelevant s -> relevance s = Relevant
-forgetIsRelevant Set = Refl
-
export
pairRelevance : (s, s' : Universe) -> relevance (max s s') = pair (relevance s) (relevance s')
pairRelevance Prop s' = Refl