documentation:
|
---------------------------------------------------------------------------
| Author : Michael Hanus
Version: November 2025
Analysis for solution completeness:
check whether functions are solution complete, i.e., calls only
non-rigid functions
---------------------------------------------------------------------------
|
sourcecode:
|
module Analysis.SolutionCompleteness
( solcompAnalysis, showSolComplete )
where
import Analysis.Types
import FlatCurry.Types
import Data.List
------------------------------------------------------------------------------
-- | The completeness analysis is a global function dependency analysis.
-- It assigns to a function a flag which is True if this function
-- is operationally complete, i.e., does not call (explicitly or implicitly)
-- a rigid function.
solcompAnalysis :: Analysis Bool
solcompAnalysis = dependencyFuncAnalysis "SolComplete" True scFunc
-- An operation is solution complete if it is defined with flexible
-- rules and depends only on solution complete operations.
scFunc :: FuncDecl -> [(QName,Bool)] -> Bool
scFunc func calledFuncs =
isFlexDefined func && all snd calledFuncs
-- (isFlexDefined fundecl):
-- Is a function defined by a flexible rule?
isFlexDefined :: FuncDecl -> Bool
isFlexDefined (Func _ _ _ _ (Rule _ e)) = isFlexExpr e
isFlexDefined (Func f _ _ _ (External _)) =
f `elem` map pre ["=:=","success","&","&>","return"]
-- Checks whether an expression is flexible, i.e., can only suspend
-- because of calls to other possibly rigid functions.
isFlexExpr :: Expr -> Bool
isFlexExpr (Var _) = True
isFlexExpr (Lit _) = True
isFlexExpr (Comb _ f args) =
f/=(pre "apply") -- apply suspends if arg 1 is unbound
&& f/=(pre "commit")
&& all isFlexExpr args
isFlexExpr (Free _ e) = isFlexExpr e
isFlexExpr (Let bs e) = all isFlexExpr (expsOfLetBind bs) &&
isFlexExpr e
isFlexExpr (Or e1 e2) = isFlexExpr e1 && isFlexExpr e2
isFlexExpr (Case ctype e bs) = ctype==Flex &&
all isFlexExpr (e : map (\(Branch _ be) ->be) bs)
isFlexExpr (Typed e _) = isFlexExpr e
-- | Show solution completeness information as a string.
showSolComplete :: AOutFormat -> Bool -> String
showSolComplete _ True = "solution complete"
showSolComplete _ False = "maybe suspend"
pre :: String -> QName
pre n = ("Prelude",n)
------------------------------------------------------------------------------
|