Haskell 递归空间泄漏

发布于 2025-01-02 22:02:31 字数 1758 浏览 4 评论 0 原文

[更新]

所以我更改了代码以使其更具可读性。 函数 dpfsSat 有两个参数,klauselMenge 是一个包含来自 X 的元素的巨大集合。 在递归过程中 klauselMenge 应该通过一些函数来减少。

import qualified Data.IntSet as Set
import qualified Data.IntMap as IntMap
import qualified Data.Vector as V

data X
    = Xin !(Int,(Set.IntSet)) deriving (Eq,Show,Ord)

type Klausel = [Atom]
type KlauselMenge = [Klausel]

dpfsSat :: Int -> KlauselMenge -> Klausel
dpfsSat fset klauselMenge = dpfsSat' fset klauselMenge []
  where
   dpfsSat' :: Int -> KlauselMenge -> Klausel -> Klausel
   dpfsSat' _ [] l = resolveDuplicateLiterals l
   dpfsSat' f k l
    | f `seq` k `seq` l `seq` False = undefined
    | [] `elem` k = []
    | ok1 = dpfsSat' f rTF l
    | ok2 = dpfsSat' f (substituteSimilarUnits (atomToTupel v2) k) l
    | ok3 = dpfsSat' f (resolveUnit1 v3 k ) ((Xin v3):l)
    | ok4 = dpfsSat' f (resolvePureLiteral v4 k) ((Xin v4):l)
    | otherwise = case (dpfsSat' f (resolveUnit1 minUnit k) ((Xin minUnit): l)) of
          [] -> dpfsSat' f ( resolveUnit1 kompl k)  ((Xin kompl): l)
          xs -> xs
    where
 rTF = resolveTrueFalse f v1 k
 minUnit = findBestLiteral4 k
 kompl   = (fst minUnit,Set.difference (Set.fromList [1..f]) (snd minUnit))
 fTF = findTrueFalse4 f k
 fSU = findSimilarAtomUnits f k
 fU  = findUnit' k
 fP  = findPureLiteral k
 ok1 = maybeToBool fTF
 ok2 = maybeToBool fSU
 ok3 = maybeToBool fU
 ok4 = maybeToBool fP
 v1  = expectJust fTF
 v2  = expectJust fSU
 v3  = expectJust fU
 v4  = expectJust fP

maybeToBool :: Maybe a -> Bool
maybeToBool (Just x) = True
maybeToBool Nothing  = False

expectJust :: Maybe a -> a
expectJust (Just x) = x
expectJust Nothing  = error "Unexpected Nothing" 

由于我不允许上传图像,因此我编写了堆配置文件的输出(-hy)。 堆里充满了 IntSet。

[Update]

So I've changed my code to make it more readable.
The function dpfsSat has two arguments, klauselMenge is a huge set with elements from X.
During the recursion klauselMenge should be reduced through some functions.

import qualified Data.IntSet as Set
import qualified Data.IntMap as IntMap
import qualified Data.Vector as V

data X
    = Xin !(Int,(Set.IntSet)) deriving (Eq,Show,Ord)

type Klausel = [Atom]
type KlauselMenge = [Klausel]

dpfsSat :: Int -> KlauselMenge -> Klausel
dpfsSat fset klauselMenge = dpfsSat' fset klauselMenge []
  where
   dpfsSat' :: Int -> KlauselMenge -> Klausel -> Klausel
   dpfsSat' _ [] l = resolveDuplicateLiterals l
   dpfsSat' f k l
    | f `seq` k `seq` l `seq` False = undefined
    | [] `elem` k = []
    | ok1 = dpfsSat' f rTF l
    | ok2 = dpfsSat' f (substituteSimilarUnits (atomToTupel v2) k) l
    | ok3 = dpfsSat' f (resolveUnit1 v3 k ) ((Xin v3):l)
    | ok4 = dpfsSat' f (resolvePureLiteral v4 k) ((Xin v4):l)
    | otherwise = case (dpfsSat' f (resolveUnit1 minUnit k) ((Xin minUnit): l)) of
          [] -> dpfsSat' f ( resolveUnit1 kompl k)  ((Xin kompl): l)
          xs -> xs
    where
 rTF = resolveTrueFalse f v1 k
 minUnit = findBestLiteral4 k
 kompl   = (fst minUnit,Set.difference (Set.fromList [1..f]) (snd minUnit))
 fTF = findTrueFalse4 f k
 fSU = findSimilarAtomUnits f k
 fU  = findUnit' k
 fP  = findPureLiteral k
 ok1 = maybeToBool fTF
 ok2 = maybeToBool fSU
 ok3 = maybeToBool fU
 ok4 = maybeToBool fP
 v1  = expectJust fTF
 v2  = expectJust fSU
 v3  = expectJust fU
 v4  = expectJust fP

maybeToBool :: Maybe a -> Bool
maybeToBool (Just x) = True
maybeToBool Nothing  = False

expectJust :: Maybe a -> a
expectJust (Just x) = x
expectJust Nothing  = error "Unexpected Nothing" 

Since I'm not allowed to upload images, I do writing the output of the heap profile (-hy).
The Heap is full of IntSet's.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡紫姑娘! 2025-01-09 22:02:31

如果 c 类似于 (1+),那么当您构建一系列 thunk (1+(1+(1+ ...)))。避免这种情况的方法是使用 seq

let k' = c u in k' `seq` a k' f l

seq 将在 a k' f l 之前强制评估 k'进行评估,因此这将在许多情况下处理空间泄漏。

然而,seq 并不是万能药,您应该阅读它的正确使用并避免滥用它

If c is something like (1+), then this can cause a leak as you build up a chain of thunks (1+(1+(1+...))). The way to avoid this is to use seq:

let k' = c u in k' `seq` a k' f l

seq will force evaluation of k' before a k' f l can be evaluated, so this will handle the space leak in many cases.

However, seq is not a panacea, and you should read up on its proper use and avoid misusing it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文