{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} module Language.REST.RuntimeTerm where import Data.Hashable import GHC.Generics (Generic) import Text.Printf import qualified Data.List as L import Language.REST.Op data RuntimeTerm = App Op [RuntimeTerm] deriving (RuntimeTerm -> RuntimeTerm -> Bool (RuntimeTerm -> RuntimeTerm -> Bool) -> (RuntimeTerm -> RuntimeTerm -> Bool) -> Eq RuntimeTerm forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: RuntimeTerm -> RuntimeTerm -> Bool $c/= :: RuntimeTerm -> RuntimeTerm -> Bool == :: RuntimeTerm -> RuntimeTerm -> Bool $c== :: RuntimeTerm -> RuntimeTerm -> Bool Eq, Eq RuntimeTerm Eq RuntimeTerm -> (RuntimeTerm -> RuntimeTerm -> Ordering) -> (RuntimeTerm -> RuntimeTerm -> Bool) -> (RuntimeTerm -> RuntimeTerm -> Bool) -> (RuntimeTerm -> RuntimeTerm -> Bool) -> (RuntimeTerm -> RuntimeTerm -> Bool) -> (RuntimeTerm -> RuntimeTerm -> RuntimeTerm) -> (RuntimeTerm -> RuntimeTerm -> RuntimeTerm) -> Ord RuntimeTerm RuntimeTerm -> RuntimeTerm -> Bool RuntimeTerm -> RuntimeTerm -> Ordering RuntimeTerm -> RuntimeTerm -> RuntimeTerm forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a min :: RuntimeTerm -> RuntimeTerm -> RuntimeTerm $cmin :: RuntimeTerm -> RuntimeTerm -> RuntimeTerm max :: RuntimeTerm -> RuntimeTerm -> RuntimeTerm $cmax :: RuntimeTerm -> RuntimeTerm -> RuntimeTerm >= :: RuntimeTerm -> RuntimeTerm -> Bool $c>= :: RuntimeTerm -> RuntimeTerm -> Bool > :: RuntimeTerm -> RuntimeTerm -> Bool $c> :: RuntimeTerm -> RuntimeTerm -> Bool <= :: RuntimeTerm -> RuntimeTerm -> Bool $c<= :: RuntimeTerm -> RuntimeTerm -> Bool < :: RuntimeTerm -> RuntimeTerm -> Bool $c< :: RuntimeTerm -> RuntimeTerm -> Bool compare :: RuntimeTerm -> RuntimeTerm -> Ordering $ccompare :: RuntimeTerm -> RuntimeTerm -> Ordering $cp1Ord :: Eq RuntimeTerm Ord, (forall x. RuntimeTerm -> Rep RuntimeTerm x) -> (forall x. Rep RuntimeTerm x -> RuntimeTerm) -> Generic RuntimeTerm forall x. Rep RuntimeTerm x -> RuntimeTerm forall x. RuntimeTerm -> Rep RuntimeTerm x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep RuntimeTerm x -> RuntimeTerm $cfrom :: forall x. RuntimeTerm -> Rep RuntimeTerm x Generic, Int -> RuntimeTerm -> Int RuntimeTerm -> Int (Int -> RuntimeTerm -> Int) -> (RuntimeTerm -> Int) -> Hashable RuntimeTerm forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a hash :: RuntimeTerm -> Int $chash :: RuntimeTerm -> Int hashWithSalt :: Int -> RuntimeTerm -> Int $chashWithSalt :: Int -> RuntimeTerm -> Int Hashable) instance Show RuntimeTerm where show :: RuntimeTerm -> String show (App Op op []) = Op -> String forall a. Show a => a -> String show Op op show (App Op op [RuntimeTerm] ts) = String -> String -> ShowS forall r. PrintfType r => String -> r printf String "%s(%s)" (Op -> String forall a. Show a => a -> String show Op op) ShowS -> ShowS forall a b. (a -> b) -> a -> b $ String -> [String] -> String forall a. [a] -> [[a]] -> [a] L.intercalate String ", " ((RuntimeTerm -> String) -> [RuntimeTerm] -> [String] forall a b. (a -> b) -> [a] -> [b] map RuntimeTerm -> String forall a. Show a => a -> String show [RuntimeTerm] ts) class ToRuntimeTerm a where toRuntimeTerm :: a -> RuntimeTerm instance ToRuntimeTerm Op where toRuntimeTerm :: Op -> RuntimeTerm toRuntimeTerm Op op = Op -> [RuntimeTerm] -> RuntimeTerm App Op op [] instance ToRuntimeTerm RuntimeTerm where toRuntimeTerm :: RuntimeTerm -> RuntimeTerm toRuntimeTerm = RuntimeTerm -> RuntimeTerm forall a. a -> a id subTerms :: RuntimeTerm -> [(RuntimeTerm, (RuntimeTerm -> RuntimeTerm))] subTerms :: RuntimeTerm -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] subTerms t :: RuntimeTerm t@(App Op f [RuntimeTerm] ts) = (RuntimeTerm t, RuntimeTerm -> RuntimeTerm forall a. a -> a id) (RuntimeTerm, RuntimeTerm -> RuntimeTerm) -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] forall a. a -> [a] -> [a] : (Int -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)]) -> [Int] -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap Int -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] st [Int 0..[RuntimeTerm] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [RuntimeTerm] ts Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1] where st :: Int -> [(RuntimeTerm, (RuntimeTerm -> RuntimeTerm))] st :: Int -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] st Int i = let ti :: RuntimeTerm ti = [RuntimeTerm] ts [RuntimeTerm] -> Int -> RuntimeTerm forall a. [a] -> Int -> a !! Int i go :: RuntimeTerm -> RuntimeTerm go RuntimeTerm t' = Op -> [RuntimeTerm] -> RuntimeTerm App Op f ([RuntimeTerm] -> RuntimeTerm) -> [RuntimeTerm] -> RuntimeTerm forall a b. (a -> b) -> a -> b $ Int -> [RuntimeTerm] -> [RuntimeTerm] forall a. Int -> [a] -> [a] take Int i [RuntimeTerm] ts [RuntimeTerm] -> [RuntimeTerm] -> [RuntimeTerm] forall a. [a] -> [a] -> [a] ++ [RuntimeTerm t'] [RuntimeTerm] -> [RuntimeTerm] -> [RuntimeTerm] forall a. [a] -> [a] -> [a] ++ Int -> [RuntimeTerm] -> [RuntimeTerm] forall a. Int -> [a] -> [a] drop (Int i Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1) [RuntimeTerm] ts go2 :: (a, a -> RuntimeTerm) -> (a, a -> RuntimeTerm) go2 (a srt, a -> RuntimeTerm toFull) = (a srt, RuntimeTerm -> RuntimeTerm go (RuntimeTerm -> RuntimeTerm) -> (a -> RuntimeTerm) -> a -> RuntimeTerm forall b c a. (b -> c) -> (a -> b) -> a -> c . a -> RuntimeTerm toFull) in ((RuntimeTerm, RuntimeTerm -> RuntimeTerm) -> (RuntimeTerm, RuntimeTerm -> RuntimeTerm)) -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] forall a b. (a -> b) -> [a] -> [b] map (RuntimeTerm, RuntimeTerm -> RuntimeTerm) -> (RuntimeTerm, RuntimeTerm -> RuntimeTerm) forall a a. (a, a -> RuntimeTerm) -> (a, a -> RuntimeTerm) go2 (RuntimeTerm -> [(RuntimeTerm, RuntimeTerm -> RuntimeTerm)] subTerms RuntimeTerm ti)