diff options
| author | Greg Brown <greg.brown01@ed.ac.uk> | 2023-01-07 21:10:30 +0000 | 
|---|---|---|
| committer | Greg Brown <greg.brown01@ed.ac.uk> | 2023-01-07 21:58:30 +0000 | 
| commit | ff65d1e285a97295708899bebdcc83ec214cd347 (patch) | |
| tree | 7a786ef895ff2dea0ba31b3c7cd7397024214a10 /src/Obs/Typing.idr | |
| parent | f38761fd38207a6d9a6cc2134384cb7115a5e998 (diff) | |
Add containers types.
Containers are syntactic sugar. They are also completely untested.
Diffstat (limited to 'src/Obs/Typing.idr')
| -rw-r--r-- | src/Obs/Typing.idr | 204 | 
1 files changed, 178 insertions, 26 deletions
diff --git a/src/Obs/Typing.idr b/src/Obs/Typing.idr index c3dcfbf..8369fe0 100644 --- a/src/Obs/Typing.idr +++ b/src/Obs/Typing.idr @@ -23,30 +23,8 @@ import Text.PrettyPrint.Prettyprinter.Render.Terminal  %default total --- Loggings ---------------------------------------------------------------------- - -mismatch : (expected, got : Doc ann) -> Logging ann a -mismatch lhs rhs = fatal $ -  hang 2 (pretty "expected" <+> line <+> lhs) <+> comma <+> line <+> -  hang 2 (pretty "got" <+> line <+> align rhs) - -typeMismatch : Doc ann -> Doc ann -> Logging ann a -typeMismatch lhs rhs = inScope "type mismatch" $ mismatch lhs rhs - -universeMismatch : Doc ann -> Doc ann -> Logging ann a -universeMismatch lhs rhs = inScope "universe mismatch" $ mismatch lhs rhs -  -- Utilities ------------------------------------------------------------------- -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 ------------------------------------------------------ @@ -102,15 +80,14 @@ check' ctx sort    let Yes Refl = decEq sort (domainSort ~> codomainSort)      | No _ => fatal "internal universe mismatch" +  rewrite functionRelevance domainSort codomainSort    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 {domainRel = _, var = Just var.val, body}) +  pure $ MkLambda {var = Just var.val, body}  check' ctx sort type (Lambda {body}) = typeMismatch (pretty "function") (pretty type) @@ -130,10 +107,58 @@ check' ctx sort    trace $ pretty {ann} "checking second has type" <++> pretty element    second <- check ctx elementSort element second -  pure $ MkPair {indexRel = _, elementRel = _, first, second} +  pure $ MkPair {first, second}  check' ctx sort type (Pair {first, second}) = typeMismatch (pretty "pair type") (pretty type) +check' ctx sort type (MkContainer {shape, position, next}) = do +  container <- matchContainer type + +  let Yes Refl = decEq sort $ +        container.inputSort ~> +        max (succ container.shapeSort) +            (container.shapeSort ~> +             max (succ container.positionSort) (container.positionSort ~> container.outputSort)) +    | No _ => fatal "internal universe mismatch" + +  info "encountered container constructor" + +  let shapeType = containerShapeType container +  trace $ pretty {ann} "checking shape has type" <++> pretty shapeType +  shape <- check ctx (container.inputSort ~> succ container.shapeSort) shapeType shape + +  shapeInstance <- doApp (weaken [relevance container.inputSort] shape) (point Nothing Here) + +  let positionType = containerPositionType container shapeInstance +  trace $ pretty {ann} "checking position has type" <++> pretty positionType +  position <- check +    { tyCtx = ctx +    , sort = container.inputSort ~> container.shapeSort ~> succ container.positionSort +    , type = positionType +    , term = position +    } + +  let positionInstance = weaken [relevance container.shapeSort, relevance container.inputSort] position +  positionInstance <- doApp positionInstance (point Nothing (There Here)) +  positionInstance <- doApp positionInstance (point Nothing Here) + +  let nextType = containerNextType container shapeInstance positionInstance +  trace $ pretty {ann} "checking next has type" <++> pretty nextType +  next <- check +    { tyCtx = ctx +    , sort = container.inputSort ~> container.shapeSort ~> container.positionSort ~> container.outputSort +    , type = nextType +    , term = next +    } + +  MkContainer +    { inputRel = relevance container.inputSort +    , shapeRel = relevance container.shapeSort +    , shape +    , position +    , next +    } +  check' ctx sort type (Absurd {contradiction}) = do    info "encountered absurd" @@ -281,6 +306,133 @@ infer' ctx (Second {arg}) = do      pure (elementSort ** (returnType, returnValue)) +infer' ctx (Container {input, output, shapeSort, positionSort}) = do +  info "encountered container" + +  (inputSort, input) <- inferType ctx input +  trace $ pretty {ann} "input type is" <++> pretty input + +  (outputSort, output) <- inferType ctx output +  trace $ pretty {ann} "output type is" <++> pretty output + +  let shapeSort = shapeSort.val +  let positionSort = positionSort.val + +  let containerSort = foldr1 max +        [ inputSort ~> succ shapeSort +        , inputSort ~> shapeSort ~> succ positionSort +        , inputSort ~> shapeSort ~> positionSort ~> outputSort +        ] +  let container = MkContainerTy {inputSort, shapeSort, positionSort, outputSort, input, output} +  let container = doContainer container + +  pure (succ containerSort ** (cast containerSort, container)) + +infer' ctx (MkContainer {shape, position, next}) = fatal "cannot infer type of container" + +infer' ctx (Shape {arg}) = do +  info "encountered Shape" + +  (sort ** (type, arg)) <- infer ctx arg +  trace $ pretty {ann} "argument type is" <++> pretty type + +  container <- matchContainer type + +  let Yes Refl = decEq sort (containerSort container) +    | No _ => fatal "internal universe mismatch" + +  let shapeType = containerShapeType container +  shape <- doShape {inputRel = relevance container.inputSort, arg} + +  pure ((container.inputSort ~> succ container.shapeSort) ** (shapeType, shape)) + +infer' ctx (Position {arg}) = do +  info "encountered Position" + +  (sort ** (type, arg)) <- infer ctx arg +  trace $ pretty {ann} "argument type is" <++> pretty type + +  container <- matchContainer type + +  let Yes Refl = decEq sort (containerSort container) +    | No _ => fatal "internal universe mismatch" + +  shape <- doShape {inputRel = relevance container.inputSort, arg} +  shape <- doApp (weaken [_] shape) (point Nothing Here) + +  let positionType = containerPositionType container shape +  position <- doPosition +    { inputRel = relevance container.inputSort +    , shapeRel = relevance container.shapeSort +    , outputRel = relevance container.outputSort +    , arg +    } + +  pure ((container.inputSort ~> container.shapeSort ~> succ container.positionSort) ** +        (positionType, position)) + +infer' ctx (Next {arg}) = +  let eq : (a, b, c, d : Universe) -> relevance (a ~> b ~> c ~> d) = relevance d +      eq a b c d = +        rewrite sym $ functionRelevance c d in +        rewrite sym $ functionRelevance b (c ~> d) in +        rewrite sym $ functionRelevance a (b ~> c ~> d) in +        Refl +  in do +  info "encountered nextIndex" + +  (sort ** (type, arg)) <- infer ctx arg +  trace $ pretty {ann} "argument type is" <++> pretty type + +  container <- matchContainer type + +  let Yes Refl = decEq sort (containerSort container) +    | No _ => fatal "internal universe mismatch" + +  shape <- doShape {inputRel = relevance container.inputSort, arg} +  shape <- doApp (weaken [_] shape) (point Nothing Here) + +  position <- doPosition +    { inputRel = relevance container.inputSort +    , shapeRel = relevance container.shapeSort +    , outputRel = relevance container.outputSort +    , arg +    } +  position <- doApp (weaken [_, _] position) (point Nothing (There Here)) +  position <- doApp position (point Nothing Here) + +  let nextType = containerNextType container shape position +  nextIndex <- doNext +    { inputRel = relevance container.inputSort +    , shapeRel = relevance container.shapeSort +    , outputRel = relevance container.outputSort +    , arg +    } + +  let next' = rewrite eq container.inputSort container.shapeSort container.positionSort container.outputSort in nextIndex + +  pure ((container.inputSort ~> container.shapeSort ~> container.positionSort ~> container.outputSort) ** +        (nextType, next')) + +infer' ctx (Sem {pred = MkLambda var pred, arg}) = do +  info "encountered extension" + +  (sort ** (type, arg)) <- infer ctx arg +  trace $ pretty {ann} "argument type is" <++> pretty type + +  container <- matchContainer type + +  let Yes Refl = decEq sort (containerSort container) +    | No _ => fatal "internal universe mismatch" + +  let predCtx = ctx ::< MkFreeVar container.outputSort container.output var.val +  (predSort, pred) <- inferType predCtx pred + +  let semSort = container.inputSort ~> max container.shapeSort (container.positionSort ~> predSort) +  semType <- doSem container predSort pred arg + +  pure (succ semSort ** (cast semSort, semType)) +  infer' ctx Bool = do      info "encountered bool"      pure (Set 1 ** (cast (Set 0), Cnstr Bool))  | 
