printing improvements, improve case eval

This commit is contained in:
2024-11-09 09:34:37 -08:00
parent 778ac056f1
commit bbd4832671
6 changed files with 67 additions and 41 deletions

View File

@@ -20,6 +20,7 @@ export let newtConfig: monaco.languages.LanguageConfiguration = {
{ open: "(", close: ")" }, { open: "(", close: ")" },
{ open: '"', close: '"' }, { open: '"', close: '"' },
{ open: "'", close: "'" }, { open: "'", close: "'" },
{ open: "/-", close: "-/" },
], ],
// symbols that can be used to surround a selection // symbols that can be used to surround a selection
surroundingPairs: [ surroundingPairs: [

View File

@@ -58,13 +58,6 @@ forceMeta (VMeta fc ix sp) = case !(lookupMeta ix) of
(Solved _ k t) => vappSpine t sp >>= forceMeta (Solved _ k t) => vappSpine t sp >>= forceMeta
forceMeta x = pure x forceMeta x = pure x
-- Force far enough to compare types
forceType : Val -> M Val
forceType (VMeta fc ix sp) = case !(lookupMeta ix) of
(Unsolved x k xs _ _ _) => pure (VMeta fc ix sp)
(Solved _ k t) => vappSpine t sp >>= forceType
forceType x = fromMaybe x <$> tryEval x
public export public export
record UnifyResult where record UnifyResult where
constructor MkResult constructor MkResult
@@ -280,7 +273,7 @@ parameters (ctx: Context)
| Just v => unify l mode t' v | Just v => unify l mode t' v
if k == k' if k == k'
then unifySpine l mode (k == k') sp sp' then unifySpine l mode (k == k') sp sp'
else error fc "vref mismatch \{show k} \{show k'} -- \{show sp} \{show sp'}" else error fc "vref mismatch \{show t'} \{show u'}"
(VU _, VU _) => pure neutral (VU _, VU _) => pure neutral
-- Lennart.newt cursed type references itself -- Lennart.newt cursed type references itself

View File

@@ -57,6 +57,18 @@ tryEval (VRef fc k _ sp) =
_ => pure Nothing _ => pure Nothing
tryEval _ = pure Nothing tryEval _ = pure Nothing
-- Force far enough to compare types
export
forceType : Val -> M Val
forceType (VMeta fc ix sp) = case !(lookupMeta ix) of
(Unsolved x k xs _ _ _) => pure (VMeta fc ix sp)
(Solved _ k t) => vappSpine t sp >>= forceType
--forceType x = fromMaybe x <$> tryEval x
forceType x = do
Just x' <- tryEval x
| _ => pure x
forceType x'
evalCase : Env -> Mode -> Val -> List CaseAlt -> M (Maybe Val) evalCase : Env -> Mode -> Val -> List CaseAlt -> M (Maybe Val)
evalCase env mode sc@(VRef _ nm _ sp) (cc@(CaseCons name nms t) :: xs) = evalCase env mode sc@(VRef _ nm _ sp) (cc@(CaseCons name nms t) :: xs) =
if nm == name if nm == name
@@ -69,7 +81,7 @@ evalCase env mode sc@(VRef _ nm _ sp) (cc@(CaseCons name nms t) :: xs) =
go env (arg :: args) (nm :: nms) = go (arg :: env) args nms go env (arg :: args) (nm :: nms) = go (arg :: env) args nms
go env args [] = Just <$> vappSpine !(eval env mode t) ([<] <>< args) go env args [] = Just <$> vappSpine !(eval env mode t) ([<] <>< args)
go env [] rest = pure Nothing go env [] rest = pure Nothing
-- FIXME not good if stuck function
evalCase env mode sc (CaseDefault u :: xs) = pure $ Just !(eval (sc :: env) mode u) evalCase env mode sc (CaseDefault u :: xs) = pure $ Just !(eval (sc :: env) mode u)
evalCase env mode sc cc = do evalCase env mode sc cc = do
debug "CASE BAIL sc \{show sc} vs \{show cc}" debug "CASE BAIL sc \{show sc} vs \{show cc}"
@@ -110,7 +122,7 @@ eval env mode (Lit fc lit) = pure $ VLit fc lit
eval env mode tm@(Case fc sc alts) = do eval env mode tm@(Case fc sc alts) = do
-- TODO we need to be able to tell eval to expand aggressively here. -- TODO we need to be able to tell eval to expand aggressively here.
sc' <- eval env mode sc sc' <- eval env mode sc
let sc' = fromMaybe sc' !(tryEval sc') sc' <- forceType sc'
pure $ fromMaybe (VCase fc !(eval env mode sc) alts) pure $ fromMaybe (VCase fc !(eval env mode sc) alts)
!(evalCase env mode sc' alts) !(evalCase env mode sc' alts)

View File

@@ -118,6 +118,20 @@ solveAutos mlen ((Unsolved fc k ctx ty AutoSolve _) :: es) = do
solveAutos mlen (take mlen mc.metas) solveAutos mlen (take mlen mc.metas)
solveAutos mlen (_ :: es) = solveAutos mlen es solveAutos mlen (_ :: es) = solveAutos mlen es
dumpEnv : Context -> M String
dumpEnv ctx =
unlines . reverse <$> go (names ctx) 0 (reverse $ zip ctx.env (toList ctx.types)) []
where
isVar : Nat -> Val -> Bool
isVar k (VVar _ k' [<]) = k == k'
isVar _ _ = False
go : List String -> Nat -> List (Val, String, Val) -> List String -> M (List String)
go _ _ [] acc = pure acc
go names k ((v, n, ty) :: xs) acc = if isVar k v
-- TODO - use Doc and add <+/> as appropriate to printing
then go names (S k) xs (" \{n} : \{pprint names !(quote ctx.lvl ty)}":: acc)
else go names (S k) xs (" \{n} = \{pprint names !(quote ctx.lvl v)} : \{pprint names !(quote ctx.lvl ty)}":: acc)
logMetas : Nat -> M () logMetas : Nat -> M ()
logMetas mstart = do logMetas mstart = do
@@ -125,14 +139,13 @@ logMetas mstart = do
top <- get top <- get
mc <- readIORef top.metas mc <- readIORef top.metas
let mlen = length mc.metas `minus` mstart let mlen = length mc.metas `minus` mstart
for_ (take mlen mc.metas) $ \case for_ (reverse $ take mlen mc.metas) $ \case
(Solved fc k soln) => info fc "solve \{show k} as \{pprint [] !(quote 0 soln)}" (Solved fc k soln) => info fc "solve \{show k} as \{pprint [] !(quote 0 soln)}"
(Unsolved fc k ctx ty User cons) => do (Unsolved fc k ctx ty User cons) => do
ty' <- quote ctx.lvl ty ty' <- quote ctx.lvl ty
let names = (toList $ map fst ctx.types) let names = (toList $ map fst ctx.types)
-- I want to know which ones are defines. I should skip the `=` bit if they match, I'll need indices in here too. env <- dumpEnv ctx
env <- for (zip ctx.env (toList ctx.types)) $ \(v, n, ty) => pure " \{n} : \{pprint names !(quote ctx.lvl ty)} = \{pprint names !(quote ctx.lvl v)}" let msg = "\{env} -----------\n \{pprint names ty'}"
let msg = "\{unlines (toList $ reverse env)} -----------\n \{pprint names ty'}"
info fc "User Hole\n\{msg}" info fc "User Hole\n\{msg}"
(Unsolved (l,c) k ctx ty kind cons) => do (Unsolved (l,c) k ctx ty kind cons) => do
tm <- quote ctx.lvl !(forceMeta ty) tm <- quote ctx.lvl !(forceMeta ty)
@@ -140,7 +153,6 @@ logMetas mstart = do
-- TODO - log constraints? -- TODO - log constraints?
addError $ E (l,c) "Unsolved meta \{show k} \{show kind} type \{pprint (names ctx) tm} \{show $ length cons} constraints" addError $ E (l,c) "Unsolved meta \{show k} \{show kind} type \{pprint (names ctx) tm} \{show $ length cons} constraints"
export export
processDecl : Decl -> M () processDecl : Decl -> M ()

View File

@@ -172,33 +172,39 @@ Eq (Tm) where
||| Pretty printer for Tm. ||| Pretty printer for Tm.
export export
pprint : List String -> Tm -> String pprint : List String -> Tm -> String
pprint names tm = render 80 $ go names tm pprint names tm = render 80 $ go 0 names tm
where where
go : List String -> Tm -> Doc parens : Nat -> Nat -> Doc -> Doc
goAlt : List String -> CaseAlt -> Doc parens a b doc = if a < b
then text "(" ++ doc ++ text ")"
else doc
goAlt names (CaseDefault t) = "_" <+> "=>" <+> go ("_" :: names) t go : Nat -> List String -> Tm -> Doc
goAlt names (CaseCons name args t) = text name <+> spread (map text args) <+> "=>" <+/> go (reverse args ++ names) t goAlt : Nat -> List String -> CaseAlt -> Doc
goAlt names (CaseLit lit t) = text (show lit) <+> "=>" <+/> go names t
go names (Bnd _ k) = case getAt k names of goAlt p names (CaseDefault t) = "_" <+> "=>" <+> go p ("_" :: names) t
goAlt p names (CaseCons name args t) = text name <+> spread (map text args) <+> "=>" <+/> go p (reverse args ++ names) t
goAlt p names (CaseLit lit t) = text (show lit) <+> "=>" <+/> go p names t
go p names (Bnd _ k) = case getAt k names of
-- Either a bug or we're printing without names
Nothing => text "BND:\{show k}" Nothing => text "BND:\{show k}"
Just nm => text "\{nm}:\{show k}" Just nm => text "\{nm}:\{show k}"
go names (Ref _ str mt) = text str go p names (Ref _ str mt) = text str
go names (Meta _ k) = text "?m:\{show k}" go p names (Meta _ k) = text "?m:\{show k}"
go names (Lam _ nm t) = text "(\\ \{nm} =>" <+> go (nm :: names) t <+> ")" go p names (Lam _ nm t) = parens 0 p $ text "\\ \{nm} =>" <+> go 0 (nm :: names) t
go names (App _ t u) = text "(" <+> go names t <+> go names u <+> ")" go p names (App _ t u) = parens 0 p $ go 0 names t <+> go 1 names u
go names (U _) = "U" go p names (U _) = "U"
go names (Pi _ nm Auto t u) = go p names (Pi _ nm Auto t u) =
text "({{" <+> text nm <+> ":" <+> go names t <+> "}}" <+> "->" <+> go (nm :: names) u <+> ")" text "({{" <+> text nm <+> ":" <+> go p names t <+> "}}" <+> "->" <+> go p (nm :: names) u <+> ")"
go names (Pi _ nm Implicit t u) = go p names (Pi _ nm Implicit t u) =
text "({" <+> text nm <+> ":" <+> go names t <+> "}" <+> "->" <+> go (nm :: names) u <+> ")" text "({" <+> text nm <+> ":" <+> go p names t <+> "}" <+> "->" <+> go p (nm :: names) u <+> ")"
go names (Pi _ nm Explicit t u) = go p names (Pi _ nm Explicit t u) =
text "((" <+> text nm <+> ":" <+> go names t <+> ")" <+> "->" <+> go (nm :: names) u <+> ")" text "((" <+> text nm <+> ":" <+> go p names t <+> ")" <+> "->" <+> go p (nm :: names) u <+> ")"
-- FIXME - probably way wrong on the names here. There is implicit binding going on -- FIXME - probably way wrong on the names here. There is implicit binding going on
go names (Case _ sc alts) = text "case" <+> go names sc <+> text "of" </> (nest 2 (line ++ stack (map (goAlt names) alts))) go p names (Case _ sc alts) = parens 0 p $ text "case" <+> go 0 names sc <+> text "of" </> (nest 2 (line ++ stack (map (goAlt 0 names) alts)))
go names (Lit _ lit) = text (show lit) go p names (Lit _ lit) = text (show lit)
go names (Let _ nm t u) = text "let" <+> text nm <+> ":=" <+> go names t </> (nest 2 $ go names u) go p names (Let _ nm t u) = parens 0 p $ text "let" <+> text nm <+> ":=" <+> go 0 names t </> (nest 2 $ go 0 names u)
-- public export -- public export
-- data Closure : Nat -> Type -- data Closure : Nat -> Type
@@ -256,9 +262,11 @@ Show Closure
covering export covering export
Show Val where Show Val where
show (VVar _ k sp) = "(%var \{show k} \{unwords $ map show (sp <>> [])})" show (VVar _ k [<]) = "%var\{show k}"
show (VRef _ nm _ sp) = "(%ref \{nm} \{unwords $ map show (sp <>> [])})" show (VVar _ k sp) = "(%var\{show k} \{unwords $ map show (sp <>> [])})"
show (VMeta _ ix sp) = "(%meta \{show ix} \{show $ length sp})" show (VRef _ nm _ [<]) = nm
show (VRef _ nm _ sp) = "(\{nm} \{unwords $ map show (sp <>> [])})"
show (VMeta _ ix sp) = "(%meta \{show ix} ..\{show $ length sp})"
show (VLam _ str x) = "(%lam \{str} \{show x})" show (VLam _ str x) = "(%lam \{str} \{show x})"
show (VPi fc str Implicit x y) = "(%pi {\{str} : \{show x}}. \{show y})" show (VPi fc str Implicit x y) = "(%pi {\{str} : \{show x}}. \{show y})"
show (VPi fc str Explicit x y) = "(%pi (\{str} : \{show x}). \{show y})" show (VPi fc str Explicit x y) = "(%pi (\{str} : \{show x}). \{show y})"

View File

@@ -63,13 +63,13 @@ comp : {A : U} {B : A -> U} {C : {a : A} -> B a -> U}
-> C (g a) -> C (g a)
comp = \f g a => f (g a) comp = \f g a => f (g a)
-- compExample : Bool -- TODO unsolved metas in dependent function composition
-- compExample : List Bool
-- compExample = comp (cons true) (cons false) nil -- compExample = comp (cons true) (cons false) nil
Nat : U Nat : U
Nat = (N : U) -> (N -> N) -> N -> N Nat = (N : U) -> (N -> N) -> N -> N
-- TODO - first underscore there, why are there two metas?
mul : Nat -> Nat -> Nat mul : Nat -> Nat -> Nat
mul = \a b N s z => a _ (b _ s) z mul = \a b N s z => a _ (b _ s) z