haga/lib/LambdaCalculus.hs

546 lines
29 KiB
Haskell
Raw Permalink Normal View History

2024-02-27 18:53:43 +01:00
{-# LANGUAGE DeriveGeneric #-}
2024-02-23 17:12:27 +01:00
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE NoImplicitPrelude #-}
module LambdaCalculus where
2024-04-16 11:47:22 +02:00
import Data.List (foldr1, intersect, last, nub, (!!), (\\))
2024-02-23 17:12:27 +01:00
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Strict as Map
import Data.Maybe
import Data.Random
import qualified Data.Text as T
2024-02-27 18:53:43 +01:00
import Data.Tuple.Extra
2024-02-23 17:12:27 +01:00
import Data.Typeable
2024-04-16 11:47:22 +02:00
import Debug.Trace as DB
2024-02-23 17:12:27 +01:00
import GA
import Pretty
import Protolude
2024-03-17 18:14:52 +01:00
import Protolude.Error
2024-02-23 17:12:27 +01:00
import Test.QuickCheck hiding (sample, shuffle)
import Test.QuickCheck.Monadic (assert, monadicIO)
import qualified Type.Reflection as Ref
2024-04-16 11:47:22 +02:00
import Utils
2024-02-23 17:12:27 +01:00
data ExpressionWeights = ExpressionWeights
{ lambdaSpucker :: Int,
lambdaSchlucker :: Int,
symbol :: Int,
variable :: Int,
constant :: Int
}
data LambdaEnviroment = LambdaEnviroment
{ functions :: (Map TypeRep [ConVal]),
constants :: (Map TypeRep [RVar ConVal]),
targetType :: TypeRep,
maxDepth :: Int,
weights :: ExpressionWeights
}
2024-02-27 18:53:43 +01:00
showSanifid :: (Show a) => a -> Text
2024-02-23 17:12:27 +01:00
showSanifid var = T.replace " -> " "To" (show var)
exampleLE :: LambdaEnviroment
exampleLE =
LambdaEnviroment
{ functions =
Map.fromList
[ ((Ref.SomeTypeRep (Ref.TypeRep @(Int -> Int -> Int))), ["(+)", "(-)", "(*)", "mod"]),
((Ref.SomeTypeRep (Ref.TypeRep @(Int -> Int -> Bool))), ["(>)", "(==)", "(>=)"]),
((Ref.SomeTypeRep (Ref.TypeRep @(Bool -> Int -> Int -> Int))), ["if'"])
],
constants =
Map.fromList
[ ((Ref.SomeTypeRep (Ref.TypeRep @(Int))), [(fmap show (uniform 0 10000 :: RVar Int))]),
((Ref.SomeTypeRep (Ref.TypeRep @(Bool))), [(fmap show (uniform True False :: RVar Bool))])
],
targetType = (Ref.SomeTypeRep (Ref.TypeRep @(Int -> Int -> Int))),
maxDepth = 10,
weights =
ExpressionWeights
{ lambdaSpucker = 1,
2024-03-04 11:36:31 +01:00
lambdaSchlucker = 2,
symbol = 2,
variable = 10,
constant = 2
2024-02-23 17:12:27 +01:00
}
}
type BoundVars = [TypeRep]
-- we need a dynamic typ with a concept of equality here, should we want to interpret the result, instead of compiling it...
type ConVal = Text
-- LambdaSpucker - adds TypeRequester#1 as bound var and returns the result of TypeRequester#2
2024-03-04 11:36:31 +01:00
data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int [TypeRequester] BoundVars | Constan ConVal deriving (Eq, Ord, Show)
2024-02-23 17:12:27 +01:00
asList :: LambdaExpression -> [TypeRequester]
asList (LambdaSpucker tr1 tr2 _) = [tr1, tr2]
asList (LambdaSchlucker tr _) = [tr]
asList (Symbol _ trs _) = trs
asList (Var _ _ trs _) = trs
asList (Constan _) = []
2024-03-04 11:36:31 +01:00
data TypeRequester = TR TypeRep (Maybe LambdaExpression) BoundVars deriving (Eq, Ord, Show)
2024-02-23 17:12:27 +01:00
toLambdaExpressionS :: TypeRequester -> Text
toLambdaExpressionS (TR typeRep (Just lambdaExpression) boundVars) = "((" <> eToLambdaExpressionS lambdaExpression <> ") :: (" <> show typeRep <> "))"
toLambdaExpressionS (TR _ (Nothing) _) = "Invalid Lambda Epr"
2024-03-17 18:14:52 +01:00
-- data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int [TypeRequester] BoundVars | Constan ConVal deriving (Eq, Ord, Show)
2024-02-23 17:12:27 +01:00
eToLambdaExpressionS :: LambdaExpression -> Text
eToLambdaExpressionS (LambdaSpucker typeRequester1 typeRequester2 boundVars) = "(\\l" <> showSanifid (last boundVars) <> show (count boundVars (last boundVars) - 1) <> " -> " <> toLambdaExpressionS typeRequester2 <> ") " <> toLambdaExpressionS typeRequester1
eToLambdaExpressionS (LambdaSchlucker typeRequester boundVars) = "\\l" <> showSanifid (last boundVars) <> show (count boundVars (last boundVars) - 1) <> " -> " <> toLambdaExpressionS typeRequester
eToLambdaExpressionS (Symbol (valS) typeRequesters _) = valS <> " " <> (unwords (map toLambdaExpressionS typeRequesters))
eToLambdaExpressionS (Var typeRep int typeRequesters _) = "l" <> showSanifid typeRep <> show int <> " " <> (unwords (map toLambdaExpressionS typeRequesters))
eToLambdaExpressionS (Constan (valS)) = valS
instance Pretty TypeRequester where
pretty = toLambdaExpressionShort
instance Individual TypeRequester
instance Pretty LambdaEnviroment where
pretty (LambdaEnviroment functions constants target _ _) = "Functions: " <> show functions <> " Constants: " <> show (Map.keys constants) <> " Target is a function: " <> show target
genTypeRequester :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar TypeRequester
genTypeRequester env depthLeft target boundVars = do
le <- genLambdaExpression env (depthLeft - 1) target boundVars
return (TR target (Just le) boundVars)
genLambdaExpression :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaExpression env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
let weightMap =
( if not (canGenSchlucker target)
then [(constant weights, genLambdaConst env depthLeft target boundVar)]
else []
)
<> ( if depthLeft > 0
then [(lambdaSpucker weights, genLambdaSpucker env depthLeft target boundVar)]
else []
)
<> ( if canGenSchlucker target
then [(lambdaSchlucker weights, genLambdaSchlucker env depthLeft target boundVar)]
else []
)
<> ( if depthLeft > 0 && doAnyMatchThatType target (Map.keys functions)
then [(symbol weights, genLambdaSymbol env depthLeft target boundVar)]
else []
)
<> ( if depthLeft > 0 && doAnyMatchThatType target boundVar
then [(variable weights, genLambdaVar env depthLeft target boundVar)]
else []
)
expres <- selectWeighted weightMap
res <- expres
return res
selectWeighted :: [(Int, a)] -> RVar a
selectWeighted x = do
let total = sum (map fst x)
selection <- uniform 1 total
return $ selectAtWeight selection (NE.fromList x)
selectAtWeight :: Int -> NonEmpty (Int, a) -> a
selectAtWeight _ (x :| []) = snd x
selectAtWeight w (x :| xs)
| fst x >= w = snd x
| otherwise = selectAtWeight (w - fst x) (NE.fromList xs)
canGenSchlucker :: TypeRep -> Bool
canGenSchlucker t = (typeRepTyCon t) == (typeRepTyCon (Ref.SomeTypeRep (Ref.TypeRep @(->))))
doAnyMatchThatType :: TypeRep -> [TypeRep] -> Bool
doAnyMatchThatType toGen available = any (doTypesMatch toGen) available
doTypesMatch :: TypeRep -> TypeRep -> Bool
doTypesMatch toGen available = elem toGen (available : (repeatedly (lastMay . typeRepArgs) available))
genLambdaSpucker :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaSpucker env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
2024-03-04 11:36:31 +01:00
lamdaTypeLength <- uniform 1 4
2024-02-23 17:12:27 +01:00
lambaTypes <- replicateM lamdaTypeLength (randomElement (Map.keys constants))
let lambaType = foldr1 mkFunTy lambaTypes
lamdaVarTypeRequester <- genTypeRequester env depthLeft lambaType boundVar
typeRequester <- genTypeRequester env depthLeft target (boundVar ++ [lambaType])
return (LambdaSpucker lamdaVarTypeRequester typeRequester (boundVar ++ [lambaType]))
genLambdaSchlucker :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaSchlucker env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
let args = typeRepArgs target
let lambaType = fromJust (head args)
let toFind = last args
2024-04-16 11:47:22 +02:00
typeRequester <- genTypeRequester env (depthLeft + 1) toFind (boundVar ++ [lambaType])
2024-02-23 17:12:27 +01:00
return (LambdaSchlucker typeRequester (boundVar ++ [lambaType]))
genLambdaConst :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaConst env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
elm <- randomElement $ fromJust (Map.lookup target constants)
res <- elm
return $ Constan res
genLambdaSymbol :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaSymbol env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
let availFunTypes = filter (doTypesMatch target) (Map.keys functions)
(tr, fun) <- randomElement $ concatMap (\l -> zip (repeat l) (fromMaybe [] (Map.lookup l functions))) availFunTypes
ret <- genLambdaSymbol' tr fun [] env depthLeft target boundVar
return ret
genLambdaSymbol' :: TypeRep -> ConVal -> [TypeRequester] -> LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaSymbol' tr v trs env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar
| tr == target = do
return $ Symbol v trs boundVar
| otherwise = do
let args = typeRepArgs tr
let param = fromJust (head args)
let rest = last args
newTypeRequ <- genTypeRequester env depthLeft param boundVar
ret <- genLambdaSymbol' rest v (trs ++ [newTypeRequ]) env depthLeft target boundVar
return ret
genLambdaVar :: LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaVar env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar = do
let availTypes = filter (doTypesMatch target) boundVar
choosenType <- randomElement $ availTypes
let tCount = count boundVar choosenType
2024-02-27 18:53:43 +01:00
indexV <- uniform 0 (tCount - 1)
2024-02-23 17:12:27 +01:00
ret <- genLambdaVar' choosenType choosenType indexV [] env depthLeft target boundVar
return ret
genLambdaVar' :: TypeRep -> TypeRep -> Int -> [TypeRequester] -> LambdaEnviroment -> Int -> TypeRep -> BoundVars -> RVar LambdaExpression
genLambdaVar' tr varType varNumber trs env@(LambdaEnviroment functions constants _ _ weights) depthLeft target boundVar
| tr == target = do
return $ Var varType varNumber trs boundVar
| otherwise = do
let args = typeRepArgs tr
let param = fromJust (head args)
let rest = last args
newTypeRequ <- genTypeRequester env depthLeft param boundVar
ret <- genLambdaVar' rest varType varNumber (trs ++ [newTypeRequ]) env depthLeft target boundVar
return ret
instance Environment TypeRequester LambdaEnviroment where
2024-02-26 13:28:51 +01:00
new env@(LambdaEnviroment _ _ target maxDepth _) = do
tr <- genTypeRequester env maxDepth target []
return tr
2024-02-23 17:12:27 +01:00
2024-02-26 13:28:51 +01:00
mutate env@(LambdaEnviroment _ _ _ maxDepth _) tr = do
2024-04-16 11:47:22 +02:00
selfCrossover <- uniform True False
co <- crossover1 env tr tr
if selfCrossover && isJust co
then do
let (tr1, tr2) = fromJust co
return $ minimumBy (compare `on` countTrsR) [tr1, tr2]
else do
let trCount = countTrsR (tr)
selectedTR <- uniform 1 trCount
let (depthAt, (TR trep _ bound)) = depthLeftAndTypeAtR tr selectedTR maxDepth
res <- genTypeRequester env depthAt trep bound
return $ replaceAtR selectedTR tr res
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
nX _ = 3 -- todo!
2024-02-27 13:20:33 +01:00
2024-02-26 13:28:51 +01:00
crossover1 env@(LambdaEnviroment _ _ _ maxDepth _) tr1 tr2 = do
2024-03-17 18:14:52 +01:00
let trCount = countTrsR tr1
selectedIndex1 <- uniform 1 trCount
2024-04-16 11:47:22 +02:00
let (depthAt1, selectedTr1@(TR _ _ bound1)) = depthLeftAndTypeAtR tr1 selectedIndex1 maxDepth
let depthLeftNeeded = depthOfTR selectedTr1
let indexes = findIndicesWhere tr2 (isCompatibleTr selectedTr1 (maxDepth - depthAt1) depthLeftNeeded) 0 0
if length indexes == 0
then return Nothing
else
( do
(selectedTr2@(TR _ _ bound2), selectedIndex2) <- randomElement indexes
selectedTr2 <- adaptBoundVars selectedTr2 bound1
selectedTr1 <- adaptBoundVars selectedTr1 bound2
let child1 = replaceAtR selectedIndex1 tr1 selectedTr2
let child2 = replaceAtR selectedIndex2 tr2 selectedTr1
return $ Just (child1, child2)
)
2024-02-23 17:12:27 +01:00
2024-02-26 13:28:51 +01:00
-- helper
2024-04-16 11:47:22 +02:00
depthOfTR :: TypeRequester -> Int
depthOfTR (TR _ (Just le@(LambdaSchlucker _ _)) _) = maximum (0:(map depthOfTR (asList le)))
depthOfTR (TR _ (Just le) _) = maximum (0:(map depthOfTR (asList le))) + 1
depthOfTR _ = error "le Not Just (depthOfTR)"
adaptBoundVars :: TypeRequester -> BoundVars -> RVar TypeRequester
2024-03-17 18:14:52 +01:00
adaptBoundVars tr@(TR _ _ bvOld) bvNew = do
newIndexMap <- generateConversionIndexMap bvOld bvNew
return $ convertTr tr bvOld bvNew newIndexMap
2024-04-16 11:47:22 +02:00
convertTr :: TypeRequester -> BoundVars -> BoundVars -> Map TypeRep (Int -> Int) -> TypeRequester
2024-03-17 18:14:52 +01:00
convertTr tr@(TR tRp (Just le) bvCurr) bvOld bvNew mapper = TR tRp (Just (convertLe le bvOld bvNew mapper)) (bvNew ++ (bvCurr \\ bvOld))
convertTr _ _ _ _ = error "le Not Just (convertTr)"
-- data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int [TypeRequester] BoundVars | Constan ConVal deriving (Eq, Ord, Show)
2024-04-16 11:47:22 +02:00
convertLe :: LambdaExpression -> BoundVars -> BoundVars -> Map TypeRep (Int -> Int) -> LambdaExpression
2024-03-17 18:14:52 +01:00
convertLe (LambdaSpucker tr1 tr2 bvCurr) bvOld bvNew mapper = LambdaSpucker (convertTrf tr1) (convertTrf tr2) (bvNew ++ (bvCurr \\ bvOld))
2024-04-16 11:47:22 +02:00
where
convertTrf tr = convertTr tr bvOld bvNew mapper
2024-03-17 18:14:52 +01:00
convertLe (LambdaSchlucker tr bvCurr) bvOld bvNew mapper = LambdaSchlucker (convertTrf tr) (bvNew ++ (bvCurr \\ bvOld))
2024-04-16 11:47:22 +02:00
where
convertTrf tr = convertTr tr bvOld bvNew mapper
2024-03-17 18:14:52 +01:00
convertLe (Symbol cv trs bvCurr) bvOld bvNew mapper = Symbol cv (map convertTrf trs) (bvNew ++ (bvCurr \\ bvOld))
2024-04-16 11:47:22 +02:00
where
convertTrf tr = convertTr tr bvOld bvNew mapper
2024-03-17 18:14:52 +01:00
convertLe (Var varType varNumber trs bvCurr) bvOld bvNew mapper = Var varType ((fromMaybe identity (Map.lookup varType mapper)) varNumber) (map convertTrf trs) (bvNew ++ (bvCurr \\ bvOld))
2024-04-16 11:47:22 +02:00
where
convertTrf tr = convertTr tr bvOld bvNew mapper
2024-03-17 18:14:52 +01:00
convertLe le@(Constan _) _ _ _ = le
2024-04-16 11:47:22 +02:00
generateConversionIndexMap :: BoundVars -> BoundVars -> RVar (Map TypeRep (Int -> Int))
2024-03-17 18:14:52 +01:00
generateConversionIndexMap bvOld bvNew = do
funcs <- mapM (\bT -> genMapper (count bvOld bT - 1) (count bvNew bT - 1)) (nub bvOld)
return $ Map.fromList $ zip (nub bvOld) funcs
2024-04-16 11:47:22 +02:00
genMapper :: Int -> Int -> RVar (Int -> Int)
genMapper i j
| i == j = return identity
| i < j = return $ \int -> if int <= i then int else int + (j - i)
| i > j = do
permutationForUnbound <- genPermutation i j
return $ genMapperRandomAssment i j permutationForUnbound
| otherwise = error "impossible case in genMapper"
genMapperRandomAssment :: Int -> Int -> [Int] -> Int -> Int
genMapperRandomAssment i j permutationForUnbound int
| int <= j = int
| int > i = int - (i - j)
| otherwise = permutationForUnbound !! (int - j - 1)
genPermutation :: Int -> Int -> RVar [Int]
2024-03-17 18:14:52 +01:00
genPermutation i j = replicateM (i - j) (uniform 0 j)
2024-04-16 11:47:22 +02:00
isCompatibleTr :: TypeRequester -> Int -> Int -> TypeRequester -> Int -> Bool
isCompatibleTr tr1@(TR trep1 _ bound1) maxDepthOfTR2 maxDepthOfNode tr2@(TR trep2 _ bound2) depthOfNode
| trep1 == trep2 = allUsedBound (usedVars bound1 tr1) bound2 && allUsedBound (usedVars bound2 tr2) bound1 && maxDepthOfTR2 >= (depthOfTR tr2) && maxDepthOfNode >= depthOfNode
| otherwise = False
2024-03-17 18:14:52 +01:00
allUsedBound :: BoundVars -> BoundVars -> Bool
allUsedBound used available = all (\x -> any (== x) available) used
usedVars :: BoundVars -> TypeRequester -> BoundVars
usedVars boundOld tr@(TR trep1 (Just (Var trp ind trs _)) _) = if any (== trp) boundOld && count boundOld trp > ind then trp : concatMap (usedVars boundOld) trs else concatMap (usedVars boundOld) trs
2024-04-16 11:47:22 +02:00
usedVars boundOld tr@(TR trep1 (Just le) _) = concatMap (usedVars boundOld) (asList le)
2024-03-17 18:14:52 +01:00
usedVars _ _ = error "Nothing in usedVars"
2024-04-16 11:47:22 +02:00
boundsConvertable :: BoundVars -> BoundVars -> Bool
boundsConvertable bv1 bv2 = length (nub bv2) == length (nub bv1) && length (intersect (nub bv1) bv2) == length (nub bv1)
2024-03-17 18:14:52 +01:00
2024-04-16 11:47:22 +02:00
findIndicesWhere :: TypeRequester -> (TypeRequester -> Int -> Bool) -> Int -> Int -> [(TypeRequester, Int)]
findIndicesWhere tr@(TR _ (Just le@(LambdaSchlucker _ _)) _) filte indx currDepth = if filte tr currDepth then (tr, indx + 1) : (findIndicesWhere' (asList le) filte (indx + 1) (currDepth)) else (findIndicesWhere' (asList le) filte (indx + 1) (currDepth))
findIndicesWhere tr@(TR _ lE _) filte indx currDepth = case lE of
Just le -> if filte tr currDepth then (tr, indx + 1) : (findIndicesWhere' (asList le) filte (indx + 1) (currDepth + 1)) else (findIndicesWhere' (asList le) filte (indx + 1) (currDepth + 1))
Nothing -> error "Nothing in findIndicesWhere"
2024-03-17 18:14:52 +01:00
2024-04-16 11:47:22 +02:00
findIndicesWhere' :: [TypeRequester] -> (TypeRequester -> Int -> Bool) -> Int -> Int -> [(TypeRequester, Int)]
findIndicesWhere' [] _ _ _ = []
findIndicesWhere' [tr] f indx currDepth = (findIndicesWhere tr f indx currDepth)
findIndicesWhere' (tr : trs) f indx currDepth = (findIndicesWhere tr f indx currDepth) ++ (findIndicesWhere' trs f (indx + countTrsR tr) currDepth)
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
replaceAtR :: Int -> TypeRequester -> TypeRequester -> TypeRequester
2024-03-04 11:36:31 +01:00
replaceAtR 1 _ with = with
2024-02-27 18:53:43 +01:00
replaceAtR i (TR tm (Just le) bV) with = TR tm (Just (replaceAt (i - 1) le with)) bV
2024-03-17 18:14:52 +01:00
replaceAtR _ (TR _ Nothing _) _ = error "Nothing in replaceAtR"
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
replaceAt :: Int -> LambdaExpression -> TypeRequester -> LambdaExpression
2024-02-23 17:12:27 +01:00
replaceAt i le@(LambdaSpucker _ _ bv) with = LambdaSpucker (fromJust (head trs)) (last trs) bv where trs = replaceInSubtreeWithIndex i (asList le) with
replaceAt i (LambdaSchlucker tr bv) with = LambdaSchlucker (replaceAtR i tr with) bv
replaceAt i le@(Symbol cv _ bv) with = Symbol cv trs bv where trs = replaceInSubtreeWithIndex i (asList le) with
replaceAt i le@(Var tr ix _ bv) with = Var tr ix trs bv where trs = replaceInSubtreeWithIndex i (asList le) with
2024-03-17 18:14:52 +01:00
replaceAt _ (Constan _) _ = error "Nothing in replaceAt"
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
replaceInSubtreeWithIndex :: Int -> [TypeRequester] -> TypeRequester -> [TypeRequester]
replaceInSubtreeWithIndex indexLeft (tr : trs) with = if countTrsR tr >= indexLeft then (replaceAtR indexLeft tr with) : trs else tr : (replaceInSubtreeWithIndex (indexLeft - countTrsR tr) trs with)
2024-03-17 18:14:52 +01:00
replaceInSubtreeWithIndex _ [] _ = error "Index not found in replaceInSubtreeWithIndex"
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
depthLeftAndTypeAtR :: TypeRequester -> Int -> Int -> (Int, TypeRequester)
2024-03-04 11:36:31 +01:00
depthLeftAndTypeAtR t 1 depthLeft = ((depthLeft - 1), t)
2024-02-27 18:53:43 +01:00
depthLeftAndTypeAtR (TR _ (Just le) _) indexLeft depthLeft = depthLeftAndTypeAt le (indexLeft - 1) (depthLeft - 1)
2024-03-17 18:14:52 +01:00
depthLeftAndTypeAtR (TR _ Nothing _) indexLeft depthLeft = error "Nothing in depthLeftAndTypeAtR"
2024-02-23 17:12:27 +01:00
depthLeftAndTypeAt :: LambdaExpression -> Int -> Int -> (Int, TypeRequester)
2024-04-16 11:47:22 +02:00
depthLeftAndTypeAt le@(LambdaSchlucker tr bv) indexLeft depthLeft = depthLeftAndTypeInSubtreeWithIndex (asList le) indexLeft (depthLeft + 1)
2024-02-23 17:12:27 +01:00
depthLeftAndTypeAt le indexLeft depthLeft = depthLeftAndTypeInSubtreeWithIndex (asList le) indexLeft depthLeft
depthLeftAndTypeInSubtreeWithIndex :: [TypeRequester] -> Int -> Int -> (Int, TypeRequester)
2024-02-27 18:53:43 +01:00
depthLeftAndTypeInSubtreeWithIndex (tr : trs) indexLeft depthLeft = if countTrsR tr >= indexLeft then depthLeftAndTypeAtR tr indexLeft depthLeft else depthLeftAndTypeInSubtreeWithIndex trs (indexLeft - countTrsR tr) depthLeft
2024-03-17 18:14:52 +01:00
depthLeftAndTypeInSubtreeWithIndex [] indexLeft depthLeft = error "Index not found in depthLeftAndTypeInSubtreeWithIndex"
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
countTrsR :: TypeRequester -> Int
2024-02-23 17:12:27 +01:00
countTrsR tr@(TR t lE _) = case lE of
2024-02-27 18:53:43 +01:00
Just le -> countTrs le + 1
Nothing -> 1
2024-02-23 17:12:27 +01:00
2024-02-27 18:53:43 +01:00
countTrs :: LambdaExpression -> Int
2024-02-23 17:12:27 +01:00
countTrs le = sum (map countTrsR (asList le))
-- Test Stuff
testConstInt :: TypeRequester
testConstInt = TR (Ref.SomeTypeRep (Ref.TypeRep @Int)) (Just (Symbol ("5") [] [])) []
testIntToClassCons :: TypeRequester
testIntToClassCons = TR (Ref.SomeTypeRep (Ref.TypeRep @(Int -> ResClass))) (Just (Symbol ("Class1") [] [])) []
testIntToClassCorrect :: TypeRequester
testIntToClassCorrect =
TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int -> ResClass)))
( Just
( LambdaSchlucker
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
( Just
( Symbol
("iteClass")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Bool)))
( Just
( Symbol
("eqInt")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Var (Ref.SomeTypeRep (Ref.TypeRep @(Int))) 0 [] []))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Constan ("1")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
(Just (Constan ("Class1")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
( Just
( Symbol
("iteClass")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Bool)))
( Just
( Symbol
("eqInt")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Var (Ref.SomeTypeRep (Ref.TypeRep @(Int))) 0 [] []))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Constan ("2")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
(Just (Constan ("Class2")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
( Just
( Symbol
("iteClass")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Bool)))
( Just
( Symbol
("eqInt")
[ ( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Var (Ref.SomeTypeRep (Ref.TypeRep @(Int))) 0 [] []))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(Int)))
(Just (Constan ("3")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
(Just (Constan ("Class3")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
),
( TR
(Ref.SomeTypeRep (Ref.TypeRep @(ResClass)))
(Just (Constan ("Class3")))
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
]
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
[(Ref.SomeTypeRep (Ref.TypeRep @(Int)))]
)
)
[]
data ResClass = Class1 | Class2 | Class3 deriving (Enum, Show)
eqInt :: Int -> Int -> Bool
eqInt a b = a == b
iteClass :: Bool -> ResClass -> ResClass -> ResClass
iteClass True c _ = c
iteClass False _ c = c
toLambdaExpressionShort :: TypeRequester -> Text
toLambdaExpressionShort (TR _ (Just lambdaExpression) _) = "(" <> eToLambdaExpressionShort lambdaExpression <> ")"
toLambdaExpressionShort (TR _ (Nothing) _) = "Invalid Lambda Epr"
-- data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int | Constan ConVal
eToLambdaExpressionShort :: LambdaExpression -> Text
eToLambdaExpressionShort (LambdaSpucker typeRequester1 typeRequester2 boundVars) = "(\\l" <> showSanifid (last boundVars) <> show (count boundVars (last boundVars) - 1) <> " -> " <> toLambdaExpressionShort typeRequester2 <> ") " <> toLambdaExpressionShort typeRequester1
2024-03-04 11:36:31 +01:00
eToLambdaExpressionShort (LambdaSchlucker typeRequester boundVars) = "(\\l" <> showSanifid (last boundVars) <> show (count boundVars (last boundVars) - 1) <> " -> " <> toLambdaExpressionShort typeRequester <> ")"
2024-02-23 17:12:27 +01:00
eToLambdaExpressionShort (Symbol (valS) typeRequesters _) = valS <> " " <> (unwords (map toLambdaExpressionShort typeRequesters))
eToLambdaExpressionShort (Var typeRep int typeRequesters _) = "l" <> showSanifid typeRep <> show int <> " " <> (unwords (map toLambdaExpressionShort typeRequesters))
eToLambdaExpressionShort (Constan (valS)) = valS
res :: Int -> ResClass
res = ((\lInt0 -> ((iteClass ((eqInt ((lInt0) :: (Int)) ((1) :: (Int))) :: (Bool)) ((Class1) :: (ResClass)) ((iteClass ((eqInt ((lInt0) :: (Int)) ((2) :: (Int))) :: (Bool)) ((Class2) :: (ResClass)) ((iteClass ((eqInt ((lInt0) :: (Int)) ((3) :: (Int))) :: (Bool)) ((Class3) :: (ResClass)) ((Class3) :: (ResClass))) :: (ResClass))) :: (ResClass))) :: (ResClass))) :: (Int -> ResClass))