summaryrefslogtreecommitdiff
path: root/src/Obs/NormalForm
diff options
context:
space:
mode:
Diffstat (limited to 'src/Obs/NormalForm')
-rw-r--r--src/Obs/NormalForm/Normalise.idr329
1 files changed, 329 insertions, 0 deletions
diff --git a/src/Obs/NormalForm/Normalise.idr b/src/Obs/NormalForm/Normalise.idr
index 2ea6296..e36e57c 100644
--- a/src/Obs/NormalForm/Normalise.idr
+++ b/src/Obs/NormalForm/Normalise.idr
@@ -1,6 +1,7 @@
module Obs.NormalForm.Normalise
import Data.Bool
+import Data.List
import Data.Nat
import Decidable.Equality
@@ -57,6 +58,14 @@ map1 : {s' : _} ->
map1 t u = subst' u (add (LogNormalForm' ann) (Left $ pure t) (Right . There))
export
+MkLambda : {rel, domainRel : _} ->
+ (var : Maybe String) ->
+ (body : NormalForm rel (domainRel :: ctx)) ->
+ NormalForm (function domainRel rel) ctx
+MkLambda {rel = Irrelevant} var body = Irrel
+MkLambda {rel = Relevant} var body = Cnstr $ Lambda {var, body, domainRel}
+
+export
doApp : {domainRel : _} ->
(fun : NormalForm (function domainRel codomainRel) ctx) ->
(arg : NormalForm domainRel ctx) ->
@@ -72,6 +81,17 @@ doApp (Cnstr t) arg = inScope "wrong constructor for apply" $ fatal t
doApp Irrel arg = pure Irrel
export
+MkPair : {indexRel, elementRel : Relevance}
+ -> (first : NormalForm indexRel ctx)
+ -> (second : NormalForm elementRel ctx)
+ -> NormalForm (pair indexRel elementRel) ctx
+MkPair {indexRel = Irrelevant, elementRel = Irrelevant, first, second} = Irrel
+MkPair {indexRel = Irrelevant, elementRel = Relevant, first, second} =
+ Cnstr $ Pair {indexRel = Irrelevant, elementRel = Relevant, prf = Relevant, first, second}
+MkPair {indexRel = Relevant, elementRel, first, second} =
+ Cnstr $ Pair {indexRel = Relevant, elementRel, prf = Relevant, first, second}
+
+export
doFst : (firstRel, secondRel : _) ->
(arg : NormalForm (pair firstRel secondRel) ctx) ->
LogNormalForm ann firstRel ctx
@@ -97,6 +117,193 @@ doSnd firstRel Relevant arg =
Cnstr t => inScope "wrong constructor for snd" $ fatal t
export
+doContainer : ContainerTy ctx -> TypeNormalForm ctx
+doContainer container =
+ Cnstr $ Pi
+ { domainSort = container.inputSort
+ , codomainSort =
+ max (succ container.shapeSort)
+ (container.shapeSort ~>
+ max (succ container.positionSort) (container.positionSort ~> container.outputSort))
+ , domain = MkDecl Nothing container.input
+ , codomain = Cnstr $ Sigma
+ { indexSort = succ container.shapeSort
+ , elementSort = container.shapeSort ~>
+ max (succ container.positionSort)
+ (container.positionSort ~> container.outputSort)
+ , index = MkDecl (Just "Shape") (cast container.shapeSort)
+ , element = Cnstr $ Pi
+ { domainSort = container.shapeSort
+ , codomainSort = max (succ container.positionSort)
+ (container.positionSort ~> container.outputSort)
+ , domain = MkDecl Nothing (Ntrl $ Var "Shape" Here)
+ , codomain = Cnstr $ Sigma
+ { indexSort = succ container.positionSort
+ , elementSort = container.positionSort ~> container.outputSort
+ , index = MkDecl (Just "Position") (cast container.positionSort)
+ , element = Cnstr $ Pi
+ { domainSort = container.positionSort
+ , codomainSort = container.outputSort
+ , domain = MkDecl Nothing (Ntrl $ Var "Position" Here)
+ , codomain = weaken [_, _, _, _, _] container.output
+ }
+ }
+ }
+ }
+ }
+
+export
+MkContainer : (inputRel, shapeRel : Relevance) ->
+ {outputRel : Relevance} ->
+ (shape : TypeNormalForm ctx) ->
+ (position : TypeNormalForm ctx) ->
+ (next : NormalForm outputRel ctx) ->
+ LogNormalForm ann Relevant ctx
+MkContainer {inputRel, shapeRel, outputRel, shape, position, next} = do
+ shape <- doApp (Sorted.weaken [inputRel] shape) (point Nothing Here)
+ position <- doApp (weaken [shapeRel, inputRel] position) (point Nothing (There Here))
+ position <- doApp position (point Nothing Here)
+ next <- doApp (weaken [shapeRel, inputRel] next) (point Nothing (There Here))
+ next <- doApp next (point Nothing Here)
+ pure $ MkLambda
+ { var = Nothing
+ , body = MkPair
+ { first = shape
+ , second = MkLambda
+ { var = Nothing
+ , body = MkPair
+ { first = position
+ , second = next
+ }
+ }
+ }
+ }
+
+export
+doShape : (inputRel : Relevance) ->
+ (arg : NormalForm Relevant ctx) ->
+ LogNormalForm ann Relevant ctx
+doShape inputRel arg =
+ let inputIndex : NormalForm inputRel (inputRel :: ctx)
+ inputIndex = point Nothing Here
+ in do
+ inputIndexed <- doApp (weaken [_] arg) inputIndex
+ body <- doFst Relevant Relevant inputIndexed
+
+ pure $ MkLambda {var = Nothing, body}
+
+export
+doPosition : (inputRel, shapeRel, outputRel : Relevance) ->
+ (arg : NormalForm Relevant ctx) ->
+ LogNormalForm ann Relevant ctx
+doPosition {inputRel, shapeRel, outputRel, arg} =
+ let inputIndex : NormalForm inputRel (inputRel :: ctx)
+ inputIndex = point Nothing Here
+ in
+ let shapeIndex : NormalForm shapeRel (shapeRel :: inputRel :: ctx)
+ shapeIndex = point Nothing Here
+ in do
+ inputIndexed <- doApp (weaken [_] arg) inputIndex
+
+ positionNextPair <- doSnd Relevant Relevant inputIndexed
+ let positionNextPair = weaken [_] positionNextPair
+
+ shapeIndexed <- doApp positionNextPair shapeIndex
+ body <- doFst Relevant outputRel shapeIndexed
+
+ pure $ MkLambda
+ { var = Nothing
+ , body = MkLambda {var = Nothing, body}
+ }
+
+export
+doNext : (inputRel, shapeRel, outputRel : Relevance) ->
+ (arg : NormalForm Relevant ctx) ->
+ LogNormalForm ann outputRel ctx
+doNext {inputRel, shapeRel, outputRel, arg} =
+ let inputIndex : NormalForm inputRel (inputRel :: ctx)
+ inputIndex = point Nothing Here
+ in
+ let shapeIndex : NormalForm shapeRel (shapeRel :: inputRel :: ctx)
+ shapeIndex = point Nothing Here
+ in do
+ inputIndexed <- doApp (weaken [_] arg) inputIndex
+
+ positionNextPair <- doSnd Relevant Relevant inputIndexed
+ let positionNextPair = weaken [_] positionNextPair
+
+ shapeIndexed <- doApp positionNextPair shapeIndex
+ body <- doSnd Relevant outputRel shapeIndexed
+
+ pure $ MkLambda
+ { var = Nothing
+ , body = MkLambda {var = Nothing, body}
+ }
+
+export
+doSem : (container : ContainerTy ctx) ->
+ (predSort : Universe) ->
+ (pred : TypeNormalForm (relevance container.outputSort :: ctx)) ->
+ (arg : NormalForm Relevant ctx) ->
+ LogNormalForm ann Relevant ctx
+doSem {container, predSort, pred, arg} = do
+ let inputVar = Nothing
+ let shapeVar = Nothing
+ let positionVar = Nothing
+
+ let inputDomain = MkDecl inputVar container.input
+
+ shape <- doShape {inputRel = relevance container.inputSort, arg}
+ let shape = Sorted.weaken [_] shape
+
+ shapeType <- doApp shape (point inputVar Here)
+ let shapeIndex = MkDecl shapeVar shapeType
+
+ position <- doPosition
+ { inputRel = relevance container.inputSort
+ , shapeRel = relevance container.shapeSort
+ , outputRel = relevance container.outputSort
+ , arg
+ }
+ let position = Sorted.weaken [_,_] position
+
+ positionType <- doApp position (point inputVar (There Here))
+ positionType <- doApp positionType (point shapeVar Here)
+ let positionDomain = MkDecl positionVar positionType
+
+ next <- doNext
+ { inputRel = relevance container.inputSort
+ , shapeRel = relevance container.shapeSort
+ , outputRel = relevance container.outputSort
+ , arg
+ }
+ let next = Sorted.weaken [_,_,_] next
+
+ next <- doApp next (point inputVar (There (There Here)))
+ next <- doApp next (point shapeVar (There Here))
+ next <- doApp next (point positionVar Here)
+
+ let f = add (LogNormalForm' ann) (Left $ pure next) (Right . There . There . There)
+ codomain <- subst' pred f
+
+ pure $ Cnstr $ Pi
+ { domainSort = container.inputSort
+ , codomainSort = max container.shapeSort (container.positionSort ~> predSort)
+ , domain = inputDomain
+ , codomain = Cnstr $ Sigma
+ { indexSort = container.shapeSort
+ , elementSort = container.positionSort ~> predSort
+ , index = shapeIndex
+ , element = Cnstr $ Pi
+ { domainSort = container.positionSort
+ , codomainSort = predSort
+ , domain = positionDomain
+ , codomain
+ }
+ }
+ }
+
+export
doIf : {rel : _} ->
(discriminant : NormalForm Relevant ctx) ->
(true, false : NormalForm rel ctx) ->
@@ -574,3 +781,125 @@ subst' Irrel f = pure Irrel
export
subst : NormalForm ~|> Hom (LogNormalForm ann) (LogNormalForm ann)
subst t f = subst' t (Left . f)
+
+export
+strengthen : (ctx' : List Relevance) ->
+ Map ctx' (LogNormalForm' ann) ctx ->
+ Map (ctx' ++ ctx) (LogNormalForm' ann) ctx
+strengthen [] f = Right
+strengthen (rel :: ctx) f = add (LogNormalForm' ann) (f Here) (strengthen ctx (f . There))
+
+-- Container Utilities ---------------------------------------------------------
+
+public export
+containerSort : (container : ContainerTy ctx) -> Universe
+containerSort container =
+ container.inputSort ~>
+ max (succ container.shapeSort)
+ (container.shapeSort ~>
+ max (succ container.positionSort) (container.positionSort ~> container.outputSort))
+
+export
+matchContainer : (type : TypeNormalForm ctx) -> Logging ann (ContainerTy ctx)
+matchContainer type@(Cnstr (Pi
+ { domainSort = inputSort
+ , codomainSort = inputCodomainSort
+ , domain = MkDecl _ input
+ , codomain = Cnstr (Sigma
+ { indexSort = succShapeSort@(Set _)
+ , elementSort = shapeElementSort
+ , index = MkDecl _ (Cnstr (Universe shapeSort))
+ , element = Cnstr (Pi
+ { domainSort = shapeSort'
+ , codomainSort = shapeCodomainSort
+ , domain = MkDecl _ (Ntrl (Var _ Here))
+ , codomain = Cnstr (Sigma
+ { indexSort = succPositionSort@(Set _)
+ , elementSort = positionElementSort
+ , index = MkDecl _ (Cnstr (Universe positionSort))
+ , element = Cnstr (Pi
+ { domainSort = positionSort'
+ , codomainSort = outputSort
+ , domain = MkDecl _ (Ntrl (Var _ Here))
+ , codomain = output'
+ })
+ })
+ })
+ })
+ })) = do
+ let Yes Refl = decEq
+ ( inputCodomainSort
+ , succShapeSort
+ , shapeElementSort
+ , shapeSort'
+ , shapeCodomainSort
+ , succPositionSort
+ , positionElementSort
+ , positionSort')
+ ( max (succ shapeSort)
+ (shapeSort ~> max (succ positionSort) (positionSort ~> outputSort))
+ , succ shapeSort
+ , shapeSort ~> max (succ positionSort) (positionSort ~> outputSort)
+ , shapeSort
+ , max (succ positionSort) (positionSort ~> outputSort)
+ , succ positionSort
+ , positionSort ~> outputSort
+ , positionSort)
+ | No _ => typeMismatch (pretty "container") (pretty type)
+
+ output <- subst' output' $
+ strengthen [_, _, _, _, _] $
+ const $ Left $ typeMismatch (pretty "container") (pretty type)
+ pure (MkContainerTy {inputSort, shapeSort, positionSort, outputSort, input, output})
+matchContainer type = typeMismatch (pretty "container") (pretty type)
+
+export
+containerShapeType : ContainerTy ctx -> TypeNormalForm ctx
+containerShapeType container =
+ Cnstr $ Pi
+ { domainSort = container.inputSort
+ , codomainSort = succ container.shapeSort
+ , domain = MkDecl Nothing container.input
+ , codomain = cast container.shapeSort
+ }
+
+export
+containerPositionType : (container : ContainerTy ctx) ->
+ (shape : TypeNormalForm (relevance container.inputSort :: ctx)) ->
+ TypeNormalForm ctx
+containerPositionType container shape =
+ Cnstr $ Pi
+ { domainSort = container.inputSort
+ , codomainSort = container.shapeSort ~> succ container.positionSort
+ , domain = MkDecl Nothing container.input
+ , codomain = Cnstr $ Pi
+ { domainSort = container.shapeSort
+ , codomainSort = succ container.positionSort
+ , domain = MkDecl Nothing shape
+ , codomain = cast container.positionSort
+ }
+ }
+
+export
+containerNextType : (container : ContainerTy ctx) ->
+ (shape : TypeNormalForm (relevance container.inputSort :: ctx)) ->
+ (position :
+ TypeNormalForm (relevance container.shapeSort :: relevance container.inputSort :: ctx)) ->
+ TypeNormalForm ctx
+containerNextType container shape position =
+ Cnstr $ Pi
+ { domainSort = container.inputSort
+ , codomainSort = container.shapeSort ~> container.positionSort ~> container.outputSort
+ , domain = MkDecl Nothing container.input
+ , codomain = Cnstr $ Pi
+ { domainSort = container.shapeSort
+ , codomainSort = container.positionSort ~> container.outputSort
+ , domain = MkDecl Nothing shape
+ , codomain = Cnstr $ Pi
+ { domainSort = container.positionSort
+ , codomainSort = container.outputSort
+ , domain = MkDecl Nothing position
+ , codomain = weaken [_, _, _] container.output
+ }
+ }
+ }