In a previous version of Symbolic Lambda Calculus, the rules were :
LTS (for Left Transitivity-Symmetry) represents both transitivity (a = b, b = c => a = c) and symmetry (a = b => b = a) It may be replaced by RTS (for Right Transitivity-Symmetry) (a = c, b = c => a = b)
An idea of simplification is to merge the two constructors LTS and SUB into one constructor LTR (for Left Transitivity-symmetry with Reduction) by introducing reduction in LTS :
Sslc> proves (LTR (APL (DBL DB0) (SMB "a")) (SMB "a")) The proof LTR (APL (DBL DB0) (SMB "a")) (SMB "a") proves APL (DBL DB0) (SMB "a") = SMB "a"or SMB "a" = APL (DBL DB0) (SMB "a") :
Sslc> proves (LTR (SMB "a") (APL (DBL DB0) (SMB "a"))) The proof LTR (SMB "a") (APL (DBL DB0) (SMB "a")) proves SMB "a" = APL (DBL DB0) (SMB "a")But with LTR with right reduction this does not work :
Sslc> proves (LTR (APL (DBL DB0) (SMB "a")) (SMB "a")) The proof LTR (APL (DBL DB0) (SMB "a")) (SMB "a") proves SMB "a" = SMB "a" Sslc> proves (LTR (SMB "a") (APL (DBL DB0) (SMB "a"))) The proof LTR (SMB "a") (APL (DBL DB0) (SMB "a")) proves SMB "a" = SMB "a"But proofs are simpler with right reduction than without.
gpRule1 = lambda "x" $ lambda "y" $ lambda "z" $ EQU (APL (apl2 parent (SMB "x") (SMB "y")) $ APL (apl2 parent (SMB "y") (SMB "z")) $ apl2 gdparent (SMB "x") (SMB "z")) ident gpAxiom1 = EQU (apl2 parent allan brenda) ident gpAxiom2 = EQU (apl2 parent brenda charles) identHere is a proof of a theorem saying that Allan is grand parent of Charles with LTR with right reduction :
gpLemma1c = apl3 gpRule1 allan brenda charles gpLemma2c = APL gpAxiom1 $ APL (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3c = LTR gpLemma2c gpLemma1c gpLemma4c = APL gpAxiom2 $ apl2 gdparent allan charles gpTheorem1c = LTR gpLemma4c gpLemma3cIt effectively proves what we want :
Sslc> proves gpTheorem1c The proof LTR (APL (EQU (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (DBL DB0)) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (DBL DB0)) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (APL (APL (APL (DBL (DBL (DBL (EQU (APL (APL (APL (SMB "parent") (DBS (DBS DB0))) (DBS DB0)) (APL (APL (APL (SMB "parent") (DBS DB0)) DB0) (APL (APL (SMB "gdparent") (DBS (DBS DB0))) DB0))) (DBL DB0))))) (SMB "allan")) (SMB "brenda")) (SMB "charles"))) proves APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles") = DBL DB0Note that in this system the truth of a sentence is represented by equality with the identity (DBL DB0).
But with LTR without right reduction itdoes not work :
Sslc> proves gpTheorem1c The proof LTR (APL (EQU (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (DBL DB0)) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (DBL DB0)) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (APL (APL (APL (DBL (DBL (DBL (EQU (APL (APL (APL (SMB "parent") (DBS (DBS DB0))) (DBS DB0)) (APL (APL (APL (SMB "parent") (DBS DB0)) DB0) (APL (APL (SMB "gdparent") (DBS (DBS DB0))) DB0))) (DBL DB0))))) (SMB "allan")) (SMB "brenda")) (SMB "charles"))) proves APL (DBL DB0) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")) = APL (APL (APL (DBL (DBL (DBL (DBL DB0)))) (SMB "allan")) (SMB "brenda")) (SMB "charles")To prove the theorem, we need a longer proof :
gpLemma1d = apl3 gpRule1 allan brenda charles gpLemma2d = APL gpAxiom1 $ APL (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3d1 = LTR gpLemma2d gpLemma1d gpLemma3d = LTR (LTR gpLemma3d1 (APL (apl2 parent brenda charles) (apl2 gdparent allan charles))) (DBL DB0) gpLemma4d = APL gpAxiom2 $ apl2 gdparent allan charles gpLemma5d = LTR gpLemma4d gpLemma3d gpTheorem1d = LTR (apl2 gdparent allan charles) gpLemma5dWith this proof, it works :
Sslc> proves gpTheorem1d The proof LTR (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")) (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (DBL DB0)) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (LTR (LTR (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (DBL DB0)) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (APL (APL (APL (DBL (DBL (DBL (EQU (APL (APL (APL (SMB "parent") (DBS (DBS DB0))) (DBS DB0)) (APL (APL (APL (SMB "parent") (DBS DB0)) DB0) (APL (APL (SMB "gdparent") (DBS (DBS DB0))) DB0))) (DBL DB0))))) (SMB "allan")) (SMB "brenda")) (SMB "charles"))) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (DBL DB0))) proves APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles") = DBL DB0
Another possibility is to define a reducing application operation :
apr r x = LTR (LTR (APL r x) (red (left (APL r x)))) (red (right (APL r x))) apr2 r x y = apr (apr r x) y apr3 r x y z = apr (apr (apr r x) y) zIf x proves a = b, and a reduces to a', and b reduces to b', then LTR x a' proves b = a', and LTR (LTR x a') b' proves a' = b'.
If we replace ordinary application by reducing application in the first proof, it will work with LTR without right reduction :
gpLemma1e = apr3 gpRule1 allan brenda charles gpLemma2e = apr gpAxiom1 $ apr (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3e = LTR gpLemma2e gpLemma1e gpLemma4e = apr gpAxiom2 $ apl2 gdparent allan charles gpTheorem1e = LTR gpLemma4e gpLemma3eThis proof gives the following result :
Sslc> proves gpTheorem1e The proof LTR (LTR (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (DBL DB0)) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (LTR (LTR (LTR (APL (EQU (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (DBL DB0)) (LTR (LTR (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))))) (APL (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))))) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles")))) (LTR (LTR (APL (LTR (LTR (APL (LTR (LTR (APL (DBL (DBL (DBL (EQU (APL (APL (APL (SMB "parent") (DBS (DBS DB0))) (DBS DB0)) (APL (APL (APL (SMB "parent") (DBS DB0)) DB0) (APL (APL (SMB "gdparent") (DBS (DBS DB0))) DB0))) (DBL DB0))))) (SMB "allan")) (DBL (DBL (APL (APL (APL (SMB "parent") (SMB "allan")) (DBS DB0)) (APL (APL (APL (SMB "parent") (DBS DB0)) DB0) (APL (APL (SMB "gdparent") (SMB "allan")) DB0)))))) (DBL (DBL (DBL DB0)))) (SMB "brenda")) (DBL (APL (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (APL (APL (APL (SMB "parent") (SMB "brenda")) DB0) (APL (APL (SMB "gdparent") (SMB "allan")) DB0))))) (DBL (DBL DB0))) (SMB "charles")) (APL (APL (APL (SMB "parent") (SMB "allan")) (SMB "brenda")) (APL (APL (APL (SMB "parent") (SMB "brenda")) (SMB "charles")) (APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles"))))) (DBL DB0))) proves APL (APL (SMB "gdparent") (SMB "allan")) (SMB "charles") = DBL DB0
Switching between LTR without or with right reduction is done by uncommenting the corresponding line and commenting the other :
then side RightSide a b (if s == LeftSide then x else y) then red (side RightSide a b (if s == LeftSide then x else y))
Another point, which is also explained here, concerns the reduction, implemented by a function called "red".
We must now give a precise definition of the "red" function.
One idea is to define a function "red1" which does one step of reduction, and repeat the application of this function until no more reduction is possible, i.e. we get a x such that red1(x) == x.
The problem with this definition is that there exist some terms (such that the fixed point of identity for example) such that iterated steps of reduction falls into a loop. To avoid this problem, we can define a "red" function which stops when a previously got result is got again.
But there also exist other terms for which iterated steps of reduction gives a succession of terms of increasing size. This can be detected if at some time we get a term which contains a previously got term. We can stop reduction at this time to avoid looping.
Since in some cases reduction could be continued but must be stopped to avoid looping, the consequence is that if x = y, we do not necessarily have red(x) == red(y). This limits the conditions of application of the LTR constructor. These conditions can be generalized by modifying the definition of this constructor :
Here is the Haskell code of the program used in this page :
module Sslc where import Data.List data Proof = AXM | EQU Proof Proof | SMB String | DB0 | DBS Proof | DBL Proof | APL Proof Proof | LTR Proof Proof deriving (Eq, Show) data Side = LeftSide | RightSide deriving (Eq, Show) shift :: Proof -> Proof -> Proof shift _ AXM = AXM shift u (EQU x y) = EQU (shift u x) (shift u y) shift _ (SMB s) = SMB s shift _ DB0 = DB0 shift u (DBS x) = if u == DBS x then DBS u else DBS (shift u x) shift u (DBL x) = DBL (shift (DBS u) x) shift u (APL x y) = APL (shift u x) (shift u y) shift u (LTR x y) = LTR (shift u x) (shift u y) subst :: Proof -> Proof -> Proof -> Proof subst1 :: Proof -> Proof -> Proof -> Proof subst u a b = if u == a then b else (if DBS u == a then u else subst1 u a b) subst1 _ AXM b = AXM subst1 u (EQU x y) b = EQU (subst u x b) (subst u y b) subst1 _ (SMB s) _ = SMB s subst1 _ DB0 _ = DB0 subst1 u (DBS x) b = DBS (subst u x b) subst1 u (DBL x) b = DBL (subst (DBS u) x (shift DB0 b)) subst1 u (APL x y) b = APL (subst u x b) (subst u y b) subst1 u (LTR x y) b = LTR (subst u x b) (subst u y b) cont :: Proof -> Proof -> Bool cont1 :: Proof -> Proof -> Bool cont x y = if x == y then True else cont1 x y cont1 AXM _ = False cont1 (EQU x y) z = (cont x z) || (cont y z) cont1 (SMB s) _ = False cont1 DB0 _ = False cont1 (DBS x) y = cont x y cont1 (DBL x) y = cont x y cont1 (APL x y) z = (cont x z) || (cont y z) cont1 (LTR x y) z = (cont x z) || (cont y z) red1 :: Proof -> Proof red1 AXM = AXM red1 (EQU x y) = EQU (red1 x) (red1 y) red1 (SMB s) = SMB s red1 DB0 = DB0 red1 (DBS x) = DBS (red1 x) red1 (DBL x) = DBL (red1 x) red1 (APL (DBL x) y) = subst DB0 x y red1 (APL x y) = APL (red1 x) (red1 y) red1 (LTR x y) = LTR (red1 x) (red1 y) red2 :: [Proof] -> [Proof] red2 [] = [] red2 (x : l) = (red1 x) : (x : l) red3 :: [Proof] -> [Proof] red3 [] = [] -- red3 (x : l) = if elem x l then (x : l) else red3 (red2 (x : l)) red3 (x : l) = case find (\y -> cont x y) l of Nothing -> red3 (red2 (x : l)) Just _ -> x : l red :: Proof -> Proof red x = case red3 (x : []) of [] -> x y : m -> y -- red x = if red1 x == x then x else red (red1 x) side :: Side -> Proof -> Proof -> Proof -> Proof side LeftSide a b AXM = a side RightSide a b AXM = b side LeftSide _ _ (EQU x y) = x side RightSide _ _ (EQU x y) = y side _ _ _ (SMB s) = SMB s side _ _ _ DB0 = DB0 side s a b (DBS x) = DBS (side s a b x) side s a b (DBL x) = DBL (side s a b x) side s a b (APL x y) = APL (side s a b x) (side s a b y) side s a b (LTR x y) = let lx = side LeftSide a b x ly = side LeftSide a b y in let rlx = red lx rly = red ly -- in if rlx == rly in if (lx == ly) || (lx == rly) || (rlx == ly) || (rlx == rly) then side RightSide a b (if s == LeftSide then x else y) -- LTR without right reduction -- then red (side RightSide a b (if s == LeftSide then x else y)) -- LTR with right reduction -- then (if s == LeftSide then (side RightSide a b x) else red (side RightSide a b y)) else LTR x y -- if red (side LeftSide a b x) == red (side LeftSide a b y) then (side RightSide a b (if s == LeftSide then x else y)) else LTR x y contSmb :: Proof -> String -> Bool contSmb x s = cont x (SMB s) abstr :: Proof -> String -> Proof -> Proof abstr1 :: Proof -> String -> Proof -> Proof abstr d v x = if (contSmb x v) then (abstr1 d v x) else x abstr1 d v AXM = AXM abstr1 d v (EQU x y) = EQU (abstr d v x) (abstr d v y) abstr1 d v (SMB s) = if v == s then d else (SMB s) abstr1 d v DB0 = DB0 abstr1 d v (DBS x) = DBS (abstr d v x) abstr1 d v (DBL x) = DBL (abstr (DBS d) v x) abstr1 d v (APL x y) = APL (abstr d v x) (abstr d v y) abstr1 d v (LTR x y) = LTR (abstr d v x) (abstr d v y) lambda :: String -> Proof -> Proof lambda v x = DBL (abstr DB0 v x) axl = SMB "a" axr = APL (SMB "a") (SMB "a") left = side LeftSide axl axr right = side RightSide axl axr proves x = do putStr ("\nThe proof\n " ++ show x ++ " \nproves\n " ++ show (left x) ++ "\n= " ++ show (right x) ++ "\n") reducesTo x = do putStr ("\n " ++ show x ++ "\nreduces to\n " ++ show (red x) ++ "\n") ident = DBL DB0 auto = DBL (APL DB0 DB0) comp f g = DBL (APL f (APL g DB0)) fix f = APL auto (comp f auto) ias = fix (DBL (APL (SMB "a") DB0)) apl2 f x y = APL (APL f x) y apl3 f x y z = APL (APL (APL f x) y) z parent = SMB "parent" gdparent = SMB "gdparent" allan = SMB "allan" brenda = SMB "brenda" charles = SMB "charles" gpRule1 = lambda "x" $ lambda "y" $ lambda "z" $ EQU (APL (apl2 parent (SMB "x") (SMB "y")) $ APL (apl2 parent (SMB "y") (SMB "z")) $ apl2 gdparent (SMB "x") (SMB "z")) ident gpAxiom1 = EQU (apl2 parent allan brenda) ident gpAxiom2 = EQU (apl2 parent brenda charles) ident gpLemma1c = apl3 gpRule1 allan brenda charles gpLemma2c = APL gpAxiom1 $ APL (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3c = LTR gpLemma2c gpLemma1c gpLemma4c = APL gpAxiom2 $ apl2 gdparent allan charles gpTheorem1c = LTR gpLemma4c gpLemma3c gpLemma1d = apl3 gpRule1 allan brenda charles gpLemma2d = APL gpAxiom1 $ APL (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3d1 = LTR gpLemma2d gpLemma1d gpLemma3d = LTR (LTR gpLemma3d1 (APL (apl2 parent brenda charles) (apl2 gdparent allan charles))) (DBL DB0) gpLemma4d = APL gpAxiom2 $ apl2 gdparent allan charles gpLemma5d = LTR gpLemma4d gpLemma3d gpTheorem1d = LTR (apl2 gdparent allan charles) gpLemma5d apr r x = LTR (LTR (APL r x) (red (left (APL r x)))) (red (right (APL r x))) apr2 r x y = apr (apr r x) y apr3 r x y z = apr (apr (apr r x) y) z gpLemma1e = apr3 gpRule1 allan brenda charles gpLemma2e = apr gpAxiom1 $ apr (apl2 parent brenda charles) $ apl2 gdparent allan charles gpLemma3e = LTR gpLemma2e gpLemma1e gpLemma4e = apr gpAxiom2 $ apl2 gdparent allan charles gpTheorem1e = LTR gpLemma4e gpLemma3e test = do proves (LTR (LTR AXM (SMB "a")) (APL (SMB "a") AXM)) proves (LTR (LTR AXM (SMB "a")) (APL AXM (SMB "a"))) proves (LTR (LTR AXM (SMB "a")) (APL AXM AXM)) reducesTo (APL (APL (DBL DB0) (DBL DB0)) (APL (DBL DB0) (SMB "a"))) reducesTo (fix ident) reducesTo (fix (DBL (APL (SMB "a") DB0)))