Display terms with correct parentheses

This commit is contained in:
Joscha 2020-11-26 17:54:58 +01:00
parent ed7179a846
commit 7d0d513735
2 changed files with 67 additions and 6 deletions

View file

@ -1,7 +1,15 @@
{-# LANGUAGE OverloadedStrings #-}
module Props.Lambda.Display module Props.Lambda.Display
( displayTerm ( findConstNames
, makeVarNamesUnique
, findVarNames
, displayTerm
) where ) where
import Data.Maybe
import Numeric.Natural
import qualified Data.Text as T import qualified Data.Text as T
import Props.Lambda.Term import Props.Lambda.Term
@ -19,13 +27,36 @@ constNames = chars ++ (mappend <$> constNames <*> chars)
chars = map T.singleton ['A'..'Z'] chars = map T.singleton ['A'..'Z']
findConstNames :: Term e (Maybe Name) v -> Term e Name v findConstNames :: Term e (Maybe Name) v -> Term e Name v
findConstNames = undefined findConstNames = mapConsts (fromMaybe "[]") -- TODO implement
makeVarNamesUnique :: Term e c (Maybe Name) -> Term e c (Maybe Name) makeVarNamesUnique :: Term e c (Maybe Name) -> Term e c (Maybe Name)
makeVarNamesUnique = undefined makeVarNamesUnique = id -- TODO implement
findVarNames :: Term e c (Maybe Name) -> Term e c Name findVarNames :: Term e c (Maybe Name) -> Term e c Name
findVarNames = undefined findVarNames = mapVars (fromMaybe "[]") -- TODO implement
displayTerm :: (e -> T.Text) -> Term e (Maybe Name) (Maybe Name) -> T.Text displayTerm :: (e -> T.Text) -> Term e Name Name -> T.Text
displayTerm = undefined displayTerm f = dTerm f []
nth :: [a] -> Natural -> Maybe a
nth [] _ = Nothing
nth (x:_) 0 = Just x
nth (_:xs) n = nth xs $ n - 1
varName :: [Name] -> Natural -> Name
varName vs i = fromMaybe e $ nth vs i
where
e = "[" <> T.pack (show i) <> "]"
dTerm :: (e -> T.Text) -> [Name] -> Term e Name Name -> T.Text
dTerm _ vs (Var i) = varName vs i
dTerm _ _ (Const c) = c
dTerm f vs (Lambda v t) = "λ" <> v <> ". " <> dTerm f (v:vs) t
dTerm f _ (Ext e) = f e
dTerm f vs (App l r) = dLeft l <> " " <> dRight r
where
dLeft t@(Lambda _ _) = "(" <> dTerm f vs t <> ")"
dLeft t = dTerm f vs t
dRight t@(Lambda _ _) = "(" <> dTerm f vs t <> ")"
dRight t@(App _ _) = "(" <> dTerm f vs t <> ")"
dRight t = dTerm f vs t

View file

@ -1,11 +1,19 @@
{-# LANGUAGE OverloadedStrings#-}
module Props.Lambda.Term module Props.Lambda.Term
( Term(..) ( Term(..)
, vars , vars
, mapVars
, consts , consts
, mapConsts
, termI
, termY
) where ) where
import Numeric.Natural import Numeric.Natural
import qualified Data.Text as T
-- | Lambda calculus term using De Bruijn indexing and expanded to deal with -- | Lambda calculus term using De Bruijn indexing and expanded to deal with
-- naming complexity and extensions. -- naming complexity and extensions.
data Term e c v data Term e c v
@ -26,8 +34,30 @@ vars (Lambda v t) = v : vars t
vars (App l r) = vars l <> vars r vars (App l r) = vars l <> vars r
vars _ = [] vars _ = []
mapVars :: (a -> b) -> Term e c a -> Term e c b
mapVars _ (Var i) = Var i
mapVars _ (Const c) = Const c
mapVars f (Lambda a t) = Lambda (f a) (mapVars f t)
mapVars f (App l r) = App (mapVars f l) (mapVars f r)
mapVars _ (Ext e) = Ext e
consts :: Term e c v -> [c] consts :: Term e c v -> [c]
consts (Const c) = [c] consts (Const c) = [c]
consts (Lambda _ t) = consts t consts (Lambda _ t) = consts t
consts (App l r) = consts l <> consts r consts (App l r) = consts l <> consts r
consts _ = [] consts _ = []
mapConsts :: (a -> b) -> Term e a v -> Term e b v
mapConsts _ (Var i) = Var i
mapConsts f (Const c) = Const (f c)
mapConsts f (Lambda v t) = Lambda v (mapConsts f t)
mapConsts f (App l r) = App (mapConsts f l) (mapConsts f r)
mapConsts _ (Ext e) = Ext e
termI :: Term e T.Text T.Text
termI = Lambda "x" (Var 0)
termY :: Term e T.Text T.Text
termY = Lambda "f" $ App
(Lambda "x" $ App (Var 1) $ App (Var 0) (Var 0))
(Lambda "x" $ App (Var 1) $ App (Var 0) (Var 0))