@@ -5,6 +5,8 @@ module GF.Command.TreeOperations (
55 ) where
66
77import PGF (Expr ,PGF ,CId ,compute ,mkApp ,unApp ,unapply ,unMeta ,exprSize ,exprFunctions )
8+ import PGF.Data (Expr (EApp ,EFun ))
9+ import PGF.TypeCheck (inferExpr )
810import Data.List
911
1012type TreeOp = [Expr ] -> [Expr ]
@@ -16,15 +18,17 @@ allTreeOps :: PGF -> [(String,(String,Either TreeOp (CId -> TreeOp)))]
1618allTreeOps pgf = [
1719 (" compute" ,(" compute by using semantic definitions (def)" ,
1820 Left $ map (compute pgf))),
21+ (" transfer" ,(" apply this transfer function to all maximal subtrees of suitable type" ,
22+ Right $ \ f -> map (transfer pgf f))), -- HL 12/24, modified from gf-3.3
1923 (" largest" ,(" sort trees from largest to smallest, in number of nodes" ,
2024 Left $ largest)),
21- (" nub" ,(" remove duplicate trees" ,
25+ (" nub\t " ,(" remove duplicate trees" ,
2226 Left $ nub)),
2327 (" smallest" ,(" sort trees from smallest to largest, in number of nodes" ,
2428 Left $ smallest)),
2529 (" subtrees" ,(" return all fully applied subtrees (stopping at abstractions), by default sorted from the largest" ,
2630 Left $ concatMap subtrees)),
27- (" funs" ,(" return all fun functions appearing in the tree, with duplications" ,
31+ (" funs\t " ,(" return all fun functions appearing in the tree, with duplications" ,
2832 Left $ \ es -> [mkApp f [] | e <- es, f <- exprFunctions e]))
2933 ]
3034
@@ -48,3 +52,18 @@ subtrees :: Expr -> [Expr]
4852subtrees t = t : case unApp t of
4953 Just (f,ts) -> concatMap subtrees ts
5054 _ -> [] -- don't go under abstractions
55+
56+ -- Apply transfer function f:C -> D to all maximal subtrees s:C of tree e and replace
57+ -- these s by the values of f(s). This modifies the 'simple-minded transfer' of gf-3.3.
58+ -- If applied to strict subtrees s of e, better use with f:C -> C only. HL 12/2024
59+
60+ transfer :: PGF -> CId -> Expr -> Expr
61+ transfer pgf f e = case inferExpr pgf (appf e) of
62+ Left _err -> case e of
63+ EApp g a -> EApp (transfer pgf f g) (transfer pgf f a)
64+ _ -> e
65+ Right _ty -> case (compute pgf (appf e)) of
66+ v | v /= (appf e) -> v
67+ _ -> e -- default case of f, or f has no computation rule
68+ where
69+ appf = EApp (EFun f)
0 commit comments