この抽象除去用コンバイン非常識可能なアルゴリズム((λ X。X)= I(λ X。Y)= K Y(λ X。M N)= S(λ X。M)(λ X。N) )すべてのアプリケーションの後に使用されるピープホールオプティマイザーを使用する。最も重要な最適化ルールはS(K x)(K y)↦K(xy)です。これは、アルゴリズムが常に指数関数的に爆発するのを停止します。
ルールセットは文字列ペアのリストとして構成されているため、新しいルールを簡単に試すことができます。この目的のために入力パーサーを再利用する特別なボーナスとして、S、K、およびIも入力コンビネーター内で受け入れられます。
ルールは無条件に適用されません。むしろ、古いバージョンと新しいバージョンの両方が保持され、最適ではないバージョンは、長さが最適なバージョンの長さを一定の定数(現在は3バイト)以上超えた場合にのみ整理されます。
出力ステージがSKKに書き換えるまで、Iを基本的なコンビネーターとして扱うことにより、スコアはわずかに改善されます。このようにして、KI = K(SKK)は、残りの最適化を混乱させることなく、出力時にSKに4バイト短縮できます。
{-# LANGUAGE ViewPatterns #-}
import qualified Data.IntMap as I
import qualified Data.List.NonEmpty as N
import System.IO
data Term
= V Int
| S
| K
| I
| A (N.NonEmpty (Int, Term, Term))
deriving (Show, Eq, Ord)
parse :: String -> (Term, String)
parse = parseApp . parse1
parseApp :: (Term, String) -> (Term, String)
parseApp (t, ' ':s) = parseApp (t, s)
parseApp (t, "") = (t, "")
parseApp (t, ')':s) = (t, ')' : s)
parseApp (t1, parse1 -> (t2, s)) =
parseApp (A (pure (appLen (t1, t2), t1, t2)), s)
parse1 :: String -> (Term, String)
parse1 (' ':s) = parse1 s
parse1 ('(':(parse -> (t, ')':s))) = (t, s)
parse1 ('S':s) = (S, s)
parse1 ('K':s) = (K, s)
parse1 ('I':s) = (I, s)
parse1 (lex -> [(i, s)]) = (V (read i), s)
ruleStrings :: [(String, String)]
ruleStrings =
[ ("1 3(2 3)", "S1 2 3")
, ("S(K(S(K1)))(S(K(S(K2)))3)", "S(K(S(K(S(K1)2))))3")
, ("S(K(S(K1)))(S(K2))", "S(K(S(K1)2))")
, ("S(K1)(K2)", "K(1 2)")
, ("S(K1)I", "1")
, ("S(S(K1)2)(K3)", "S(K(S1(K3)))2")
, ("S(SI1)I", "S(SSK)1")
]
rules :: [(Term, Term)]
rules = [(a, b) | (parse -> (a, ""), parse -> (b, "")) <- ruleStrings]
len :: Term -> Int
len (V _) = 1
len S = 1
len K = 1
len I = 3
len (A ((l, _, _) N.:| _)) = l
appLen :: (Term, Term) -> Int
appLen (t1, S) = len t1 + 1
appLen (t1, K) = len t1 + 1
appLen (K, I) = 2
appLen (t1, t2) = len t1 + len t2 + 2
notA :: Term -> Bool
notA (A _) = False
notA _ = True
alt :: N.NonEmpty Term -> Term
alt ts =
head $
N.filter notA ts ++
[A (N.nub (a N.:| filter (\(l, _, _) -> l <= minLen + 3) aa))]
where
a@(minLen, _, _) N.:| aa =
N.sort $ do
A b <- ts
b
match :: Term -> Term -> I.IntMap Term -> [I.IntMap Term]
match (V i) t m =
case I.lookup i m of
Just ((/= t) -> True) -> []
_ -> [I.insert i t m]
match S S m = [m]
match K K m = [m]
match I I m = [m]
match (A a) (A a') m = do
(_, t1, t2) <- N.toList a
(_, t1', t2') <- N.toList a'
m1 <- match t1 t1' m
match t2 t2' m1
match _ _ _ = []
sub :: I.IntMap Term -> Term -> Term
sub _ S = S
sub _ K = K
sub _ I = I
sub m (V i) = m I.! i
sub m (A a) =
alt $ do
(_, t1, t2) <- a
pure (sub m t1 & sub m t2)
optimize :: Term -> Term
optimize t = alt $ t N.:| [sub m b | (a, b) <- rules, m <- match a t I.empty]
infixl 5 &
(&) :: Term -> Term -> Term
t1 & t2 = optimize (A (pure (appLen (t1, t2), t1, t2)))
elim :: Int -> Term -> Term
elim n (V ((== n) -> True)) = I
elim n (A a) =
alt $ do
(_, t1, t2) <- a
pure (S & elim n t1 & elim n t2)
elim _ t = K & t
paren :: String -> Bool -> String
paren s True = "(" ++ s ++ ")"
paren s False = s
output :: Term -> Bool -> String
output S = const "S"
output K = const "K"
output I = paren "SKK"
output (V i) = \_ -> show i ++ " "
output (A ((_, K, I) N.:| _)) = paren "SK"
output (A ((_, t1, t2) N.:| _)) = paren (output t1 False ++ output t2 True)
convert :: Int -> Term -> Term
convert 0 t = t
convert n t = convert (n - 1) (elim n t)
process :: String -> String
process (lex -> [(n, lex -> [((`elem` ["=", "->"]) -> True, parse -> (t, ""))])]) =
output (convert (read n) t) False
main :: IO ()
main = do
line <- getLine
putStrLn (process line)
hFlush stdout
main
オンラインでお試しください!
出力
- S(KS)K
- S(K(SS(KK)))(S(KK)S)
- S(K(SS))(S(KK)K)
- S(K(SS(KK)))(S(KK)(S(KS)(S(K(S(SKK)))K))))
- S(K(S(K(SS(SK))))))(S(K(SS(SK)))(S(SKK)(SKK)))
- KK
- S(K(S(S(KS))(S(K(S(SKK)))K))))(S(KK)K)
- S(K(SS(K(S(KK)(S(SKK)(SKK))))))(S(SSK(KS))(S(S(KS)(S(KK)(S(KS)) K)))(K(S(K(S(SSK)))K))))
- S(K(S(KK)))(S(K(S(S(SKK)(SKK))))K)
- SK
- S(KS)(S(KK)(S(K(SS))(S(KK)K)))
- S(K(SS(K(S(KK)K))))(S(KK)(S(KS)(S(SSK(KS))(S(K(SS))(S(KK)K) ))))
- S(K(S(K(S(K(SS(KK)))(S(KK)S))))))(S(K(SS(KK))))(S(KK)(S(KS) (S(K(S(SKK)))K))))
- S(K(S(K(S(K(SS(KK)))(S(KK)S))))))(S(K(S(SKK)))K)
- S(K(S(K(S(KS)K))))(S(KS)K)
- S(K(S(KS)K))
- S(K(S(K(S(K(SS(K(S(S(KS)(S(KK)(SSK))))(K(S(SKK)(SKK))))))(S (KK)(S(KS)K)))))))(S(K(SS(K(SSK)))))(S(KK)(S(KS)(S(KK)(SSK)))) )
- SSS(KK)
- KK
- S(KK)(S(KK)(S(S(KS)K)(S(K(S(SKK)))(S(K(S(SKK)))K))))
- S(S(KS)(S(KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K))))))(K(S(K(S( S(KS)(S(K(S(SKK)))K))))(S(KK)K)))
- S(KK)
- S(KS)(S(KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K)))))
- S(K(S(K(S(KS)K)))))(S(K(S(S(KS)(S(KK)(S(K(SS))(S(KK)K))) )))(S(KK)(S(K(SS))(S(KK)K)))))
- S(KS)(S(KK)(S(KS)K))
- S(S(KS)(S(KK)(S(KS)(S(KK)(S(K(S(K(SS(KK)))))(S(KS)(S(KK)(S (SSK(KS))(S(KS)(S(SKK)(SKK)))))))))))(K(S(S(KS)(S(K(S(K(S(KS) )(S(K(S(KS))(S(K(S(SKK)))K)))))))))(S(K(S(SKK)))K)))(S(K( S(K(S(KK)K))))(S(K(S(SKK)))K)))))
- S(K(S(K(S(K(SS(K(S(K(S(S(KS)(S(K(S(SKK))K))))(S(KK)K)) )))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K(SS))(S(KK)K)))))(S( KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K)))))))
- K(S(KK))
- S(K(S(K(S(K(S(K(S(KS)K))))(S(K(S(S(KS)(S(KK)(S(K(SS))( S(KK)K))))))K))))))(S(K(S(S(KS)(S(KK)(S(K(SS))(S(KK)K))) )))(S(KK)(S(K(SS))(S(KK)K)))))
- S(KK)(S(K(SSS(KK))))
- K(SSS(KK))
- S(K(SS(K(S(S(KS)(S(KK)(S(KS)K)))(K(S(K(S(SKK)))K)))))(S (KK)(S(KS)(SS(S(S(KS)(S(KK)(S(KS)(S(K(S(KS)(S(KK)(S(KS)K)))) ))))))(KK))))
- S(K(S(K(S(K(S(K(SS(KK)))(S(KK)S)))))))(S(K(SS(K(S(KK)K) )))(S(KK)(SSS(KS))))
- S(K(S(K(S(KK)K))))
- S(K(S(K(S(K(S(K(SS(K(S(K(S(S(SKK))K))))(S(KK)(S(KS)(S(KK)) (S(K(SS(K(S(K(S(SKK)))K))))(S(KK)(S(K(SS))(S(KK)K))))))) ))))))(S(K(S(S(KS)(S(K(S(SKK)))K))))(S(KK)K))
- S(K(SS(K(S(K(SS(K(S(K(S(S(SKK)))K))))(S(KK)(S(KS)(SS(S(S(KS) (S(KK)(S(KS)(S(K(S(SKK)))K)))))(KK))))))))(S(KK)(S(KS)(S( KK)(S(K(S(K(S(K(S(K(S(K(SS(KK)))(S(KK)S))))))))(S(K(SS (KK)))(S(KK)(S(KS)(S(K(S(KS)(S(KK)(S(KS)K))))))))))))
- S(KK)(S(K(S(K(S(KK)(S(KK)K)))))(SS(SK)))
- K(S(K(SSS(KK))))
- S(K(S(K(S(K(S(K(S(K(S(K(S(K(SS(K(S(K(S(S(KS)(S(K(S(SKK )))K))))(S(KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K(SS) ))(S(KK)K)))))(S(KK)(S(KS)K))))))))(S(K(SS(K(S(K(SS)))(S( KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K(SS))(S(KK)K)) )))(S(KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K))))))
- S(K(S(KK)))(S(KS)(S(KK)(S(K(S(KK)(S(KK)K)))))))
- S(K(SS(K(S(S(KS)(S(KK)(S(KS)K)))(K(S(K(S(SKK)))K)))))(S (KK)(S(KS)(S(KK)(S(K(S(K(S(K(SS(K(S(K(SS))(S(KK)K)))))(S (KK)(S(KS)K)))))))(S(K(SS(K(S(KK)(S(K(SS))K))))))(S(KK)(S( K(SS))(S(KK)(S(K(S(K(S(KK)(S(KS)K)))))(S(KS)K)))))))))))
- S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(SS(K(S(K(S(S(KS) (S(K(S(SKK)))K))))(S(KK)K))))))(S(KK)(S(KS)K))))))(S(K(SS (K(S(K(SS))(S(KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S( K(SS))(S(KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K(SS))) (S(KK)K)))))(S(KK)(S(KS)K))))))))(S(K(SS(K(S(K(SS))(S(KK) K)))))(S(KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K)))))))
- K(K(K(K(K(S(KK)(S(KK)(S(K(SS(SK)))(SSK)))))))))))
- S(KK)(S(K(S(KK)(S(KK)(S(KK)(S(KK)K)))))))
- S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(S(K(SS(K(S( K(S(S(KS))(S(K(S(SKK)))K))))(S(KK)K)))))(S(KK)(S(KS)K)))) ))(S(K(SS(K(S(K(SS))(S(KK)K))))))(S(KK)(S(KS)K))))))(S( K(SS(K(S(K(SS))(S(KK)K))))))(S(KK)(S(KS)K)))))))(S(K(SS(K (S(K(SS))(S(KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K( SS))(S(KK)K)))))(S(KK)(S(KS)K)))))))))S(K(SS(K(S(K(SS)))(S (KK)K)))))(S(KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K)))))))
- S(K(S(K(S(K(S(K(S(K(SS(K(S(K(SS(K(S(K(SS(KK)))(S(KK)(S( KS)(S(K(S(SKK)))K)))))))(S(KK)(S(KS)(S(KK)(S(SSK(KS)))(S(K(SS) ))(S(KK)K))))))))))(S(KK)(S(KS)(S(KK)(S(K(SS(K(S(KK)(S(KS) )(S(KK)(S(K(SS(K(S(KK)(S(KS)K))))))(S(KK)(S(K(SS))(S(KK)(S (K(SS(K(S(KK)K))))(S(KK)S))))))))))))(S(KK)(S(K(SS))K)) ))))))))(S(K(SS(K(S(KK)(S(K(S(S(KS)(S(KK)(S(K(SS))(S(KK)) K))))))(S(KK)(S(K(SS))(S(KK)K))))))))(S(KK)S))))))(S(K (SS(K(S(K(S(S(KS)(S(KK)(S(K(SS))(S(KK)K))))))(S(KK)(S(K( SS))(S(KK)K))))))))(S(KK)(S(KS)(S(KK)(S(K(S(K(S(KS)(S(KK)( S(KS)K))))))(S(KS)(S(KK)(S(K(SS))(S(KK)K))))))))))
- S(K(SS(K(SS(S(S(KS)(S(KK)S)))(KK)))))S(KK)(S(KS)(S(K(S(K (S(KS)(S(KK)(S(KS)(S(KK)(S(K(S(K(S(K(SS(K(S(K(S(S(KS)(S( KK)(S(K(SS))(S(KK)K))))))(S(KK)(S(K(SS))(S(KK)K))))))(S (KK)(S(KS)K)))))))))))))))(S(K(S(S(KS))(S(KK)(S(K(SS))(S( KK)(S(K(S(K(S(KS)K)))))(S(K(SS(K(S(K(SS))(S(KK)K)))))(S( KK)(S(KS)(S(KK)(S(K(SS))(S(KK)K))))))))))))S(KK)(S(K(S (K(S(KK)(S(KS)(S(KK)(S(K(SS(K(S(KK)(S(KS)K)))))(S(KK)(S(K (SS))K)))))))))(S(KS)(S(KK)(S(K(SS(K(S(KK)K)))))(S(KK)(S( KS)(S(SSK(KS))(S(K(SS(KK)))(S(KK)(S(KS)(S(K(S(S(SKK))K)))))))) )))))))))
- K(S(K(S(KK)(S(K(S(KK)(S(K(S(KK)(S(KK)K))))))))))))))
- S(KK)(S(K(S(K(S(KK)(S(K(S(K(S(KK)(S(K(S(K(S(KK)(S(K(S( K(S(KK)(S(K(S(KK)))(S(K(S(SKK)))K))))))(S(K(S(SKK)))K))) )))(S(K(S(SKK)))K)))))))(S(K(S(SKK)))K))))))(S(K(S(SKK)))) K))
- S(K(S(K(S(K(S(K(S(K(S(KK)))(S(K(SS(K(S(K(S(S(KS)(S(K( S(SKK)))K))))(S(KK)K))))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S (K(SS))(S(KK)K)))))(S(KK)(S(KS)K)))))))(S(K(SS(K(S(K(SS) )(S(KK)K)))))(S(KK)(S(KS)(S(KK)(S(K(S(K(S(KK)(S(KK)(S(KK)) (S(KK)K)))))))(S(K(SS))(S(KK)K))))))))