record identifier names for better printing

This commit is contained in:
William Ball 2024-11-11 14:10:27 -08:00
parent 7426594134
commit acb3fe9d6c
4 changed files with 43 additions and 57 deletions

View file

@ -3,48 +3,38 @@
module Expr where module Expr where
import Data.Function (on) import Data.Function (on)
import Data.List (genericDrop)
data Expr where data Expr where
Var :: Integer -> Expr Var :: Integer -> String -> Expr
Star :: Expr Star :: Expr
Square :: Expr Square :: Expr
App :: Expr -> Expr -> Expr App :: Expr -> Expr -> Expr
Abs :: Expr -> Expr -> Expr Abs :: String -> Expr -> Expr -> Expr
Pi :: Expr -> Expr -> Expr Pi :: String -> Expr -> Expr -> Expr
deriving (Show, Eq) deriving (Show, Eq)
occursFree :: Integer -> Expr -> Bool occursFree :: Integer -> Expr -> Bool
occursFree n (Var k) = n == k occursFree n (Var k _) = n == k
occursFree _ Star = False occursFree _ Star = False
occursFree _ Square = False occursFree _ Square = False
occursFree n (App a b) = on (||) (occursFree n) a b occursFree n (App a b) = on (||) (occursFree n) a b
occursFree n (Abs a b) = occursFree n a || occursFree (n + 1) b occursFree n (Abs _ a b) = occursFree n a || occursFree (n + 1) b
occursFree n (Pi a b) = occursFree n a || occursFree (n + 1) b occursFree n (Pi _ a b) = occursFree n a || occursFree (n + 1) b
{- --------------------- PRETTY PRINTING ----------------------------- -} {- --------------------- PRETTY PRINTING ----------------------------- -}
-- TODO : store parsed identifiers for better printing -- TODO : store parsed identifiers for better printing
genName :: Integer -> String
genName k = case genericDrop k ["x", "y", "z", "w", "u", "v"] of
[] -> 'x' : show (k - 6)
(v : _) -> v
pretty :: Expr -> String pretty :: Expr -> String
pretty = helper 0 pretty (Var _ s) = s
where pretty Star = "*"
helper :: Integer -> Expr -> String pretty Square = ""
helper k (Var n) = genName $ k - n - 1 pretty (App e1 e2) = "(" ++ pretty e1 ++ " " ++ pretty e2 ++ ")"
helper _ Star = "*" pretty (Abs x ty b) = "" ++ x ++ " : " ++ pretty ty ++ " . " ++ pretty b ++ ")"
helper _ Square = "" pretty (Pi x ty b) =
helper k (App e1 e2) = "(" ++ helper k e1 ++ " " ++ helper k e2 ++ ")" if occursFree 0 b then
helper k (Abs ty b) = "(∏" ++ x ++ " : " ++ pretty ty ++ " . " ++ pretty b ++ ")"
"" ++ genName k ++ " : " ++ helper k ty ++ " . " ++ helper (k + 1) b ++ ")" else
helper k (Pi ty b) = "(" ++ pretty ty ++ " -> " ++ pretty b ++ ")"
if occursFree 0 b
then
"(∏" ++ genName k ++ " : " ++ helper k ty ++ " . " ++ helper (k + 1) b ++ ")"
else "(" ++ helper k ty ++ " -> " ++ helper (k + 1) b ++ ")"
{- --------------- ACTUAL MATH STUFF ---------------- -} {- --------------- ACTUAL MATH STUFF ---------------- -}
@ -53,46 +43,41 @@ isSort Star = True
isSort Square = True isSort Square = True
isSort _ = False isSort _ = False
mapIndices :: (Integer -> Expr) -> Expr -> Expr
mapIndices f (Var n) = f n
mapIndices _ Star = Star
mapIndices _ Square = Square
mapIndices f (App m n) = App (mapIndices f m) (mapIndices f n)
mapIndices f (Abs m n) = Abs (mapIndices f m) (mapIndices f n)
mapIndices f (Pi m n) = Pi (mapIndices f m) (mapIndices f n)
incIndices :: Expr -> Expr incIndices :: Expr -> Expr
incIndices = mapIndices (Var . (+ 1)) incIndices (Var n x) = Var (n + 1) x
incIndices Star = Star
decIndices :: Expr -> Expr incIndices Square = Square
decIndices = mapIndices (Var . subtract 1) incIndices (App m n) = App (incIndices m) (incIndices n)
incIndices (Abs x m n) = Abs x (incIndices m) (incIndices n)
incIndices (Pi x m n) = Pi x (incIndices m) (incIndices n)
-- substitute s for 0 *AND* decrement indices; only use after reducing a redex. -- substitute s for 0 *AND* decrement indices; only use after reducing a redex.
subst :: Expr -> Expr -> Expr subst :: Expr -> Expr -> Expr
subst s (Var 0) = s subst s (Var 0 _) = s
subst _ (Var n) = Var $ n - 1 subst _ (Var n s) = Var (n - 1) s
subst _ Star = Star subst _ Star = Star
subst _ Square = Square subst _ Square = Square
subst s (App m n) = App (subst s m) (subst s n) subst s (App m n) = App (subst s m) (subst s n)
subst s (Abs m n) = Abs (subst s m) (subst s n) subst s (Abs x m n) = Abs x (subst s m) (subst s n)
subst s (Pi m n) = Pi (subst s m) (subst s n) subst s (Pi x m n) = Pi x (subst s m) (subst s n)
substnd :: Expr -> Expr -> Expr substnd :: Expr -> Expr -> Expr
substnd s (Var n) = if n == 0 then s else Var n substnd s (Var 0 _) = s
substnd _ (Var n s) = Var (n - 1) s
substnd _ Star = Star substnd _ Star = Star
substnd _ Square = Square substnd _ Square = Square
substnd s (App m n) = App (substnd s m) (substnd s n) substnd s (App m n) = App (substnd s m) (substnd s n)
substnd s (Abs m n) = Abs (substnd s m) (substnd s n) substnd s (Abs x m n) = Abs x (substnd s m) (substnd s n)
substnd s (Pi m n) = Pi (substnd s m) (substnd s n) substnd s (Pi x m n) = Pi x (substnd s m) (substnd s n)
betaReduce :: Expr -> Expr betaReduce :: Expr -> Expr
betaReduce (Var k) = Var k betaReduce (Var k s) = Var k s
betaReduce Star = Star betaReduce Star = Star
betaReduce Square = Square betaReduce Square = Square
betaReduce (App (Abs _ v) n) = subst n v betaReduce (App (Abs _ _ v) n) = subst n v
betaReduce (App m n) = App (betaReduce m) (betaReduce n) betaReduce (App m n) = App (betaReduce m) (betaReduce n)
betaReduce (Abs t v) = Abs (betaReduce t) (betaReduce v) betaReduce (Abs x t v) = Abs x (betaReduce t) (betaReduce v)
betaReduce (Pi t v) = Pi (betaReduce t) (betaReduce v) betaReduce (Pi x t v) = Pi x (betaReduce t) (betaReduce v)
betaNF :: Expr -> Expr betaNF :: Expr -> Expr
betaNF e = if e == e' then e else betaNF e' betaNF e = if e == e' then e else betaNF e'

View file

@ -3,7 +3,7 @@ module Main where
import Expr import Expr
import Parser import Parser
import System.IO import System.IO
import Check -- import Check
main :: IO () main :: IO ()
main = do main = do
@ -12,7 +12,8 @@ main = do
input <- getLine input <- getLine
case pAll input of case pAll input of
Left err -> putStrLn err Left err -> putStrLn err
Right expr -> case findType [] expr of Right expr -> putStrLn $ pretty expr
Just ty -> putStrLn $ pretty expr ++ " : " ++ pretty ty -- Right expr -> case findType [] expr of
Nothing -> putStrLn $ "Unable to find type for " ++ pretty expr ++ "!" -- Just ty -> putStrLn $ pretty expr ++ " : " ++ pretty ty
-- Nothing -> putStrLn $ "Unable to find type for " ++ pretty expr ++ "!"
main main

View file

@ -43,7 +43,7 @@ pVar = label "variable" $ lexeme $ do
var <- pIdentifier var <- pIdentifier
binders <- get binders <- get
case elemIndex var binders of case elemIndex var binders of
Just i -> return $ Var $ fromIntegral i Just i -> return $ Var (fromIntegral i) var
Nothing -> customFailure $ UnboundVariable var binders Nothing -> customFailure $ UnboundVariable var binders
defChoice :: NE.NonEmpty String -> Parser () defChoice :: NE.NonEmpty String -> Parser ()
@ -60,7 +60,7 @@ pLAbs = lexeme $ label "λ-abstraction" $ do
modify (ident :) modify (ident :)
body <- pExpr body <- pExpr
modify $ drop 1 modify $ drop 1
pure $ Abs ty body pure $ Abs ident ty body
pPAbs :: Parser Expr pPAbs :: Parser Expr
pPAbs = lexeme $ label "Π-abstraction" $ do pPAbs = lexeme $ label "Π-abstraction" $ do
@ -72,7 +72,7 @@ pPAbs = lexeme $ label "Π-abstraction" $ do
modify (ident :) modify (ident :)
body <- pExpr body <- pExpr
modify $ drop 1 modify $ drop 1
pure $ Pi ty body pure $ Pi ident ty body
pApp :: Parser Expr pApp :: Parser Expr
pApp = foldl1 App <$> some pTerm pApp = foldl1 App <$> some pTerm

View file

@ -63,7 +63,7 @@ executable lambda-D
-- Modules included in this executable, other than Main. -- Modules included in this executable, other than Main.
other-modules: Expr other-modules: Expr
Check -- Check
Parser Parser
-- LANGUAGE extensions used by modules in this package. -- LANGUAGE extensions used by modules in this package.