fork download
  1. ----------------------------------------------------------------------------
  2. -- HNU CE 데이터베이스(2025년 2학기 02분반): FD 관련 프로그래밍 과제
  3. ----------------------------------------------------------------------------
  4. -- 이름: 이재혁
  5. -- 학번: 20210501
  6. ----------------------------------------------------------------------------
  7.  
  8. import Data.List
  9. -- representing sets withi lists
  10.  
  11. subset xs ys = null (xs\\ys) -- subset test in terms of set subtraction
  12.  
  13. -- functional dependency A B C -> D E encoded as (["A","B","C"],["D","E"])
  14. type FD = ([Attr], [Attr])
  15. type Attr = String -- attributes are represented as strings
  16.  
  17.  
  18. -- 3.2.4절 Algorithm 3.7
  19. closure :: [FD] -> [Attr] -> [Attr]
  20. closure fds xs = if xs/=xs1 then closure fds xs1 else sort xs
  21. where xs1 = foldr union xs [cs | (bs,cs) <- fds, bs `subset` xs]
  22.  
  23. -- fd가 기존의 fds로부터 유도 가능한지 검사 (closure 활용한 간단한 함수)
  24. is_derived_from :: FD -> [FD] -> Bool
  25. is_derived_from fd fds = all (`elem` closureSet) rhs
  26. where
  27. lhs = fst fd
  28. rhs = snd fd
  29. closureSet = closure fds lhs
  30.  
  31.  
  32.  
  33. -- 3.2.7절 관련 fds의 basis인지 검사
  34. is_basis_of :: [FD] -> [FD] -> Bool
  35. is_basis_of basis fds =
  36. equivalent basis fds &&
  37. all singletonRHS basis &&
  38. all nonredundant basis &&
  39. all minimalLHS basis
  40. where
  41.  
  42. singletonRHS (_, rhs) = length rhs == 1
  43. nonredundant fd = not ((is_derived_from fd (remove fd basis)))
  44.  
  45. minimalLHS (lhs, rhs) =
  46. all (\a -> not (is_derived_from (lhs \\ [a], rhs) basis)) lhs
  47.  
  48. remove x = filter (/= x)
  49. equivalent a b =
  50. all (`is_derived_from` a) b &&
  51. all (`is_derived_from` b) a
  52.  
  53.  
  54. -- 3.2.7절 basis가 미니멀한지 검사
  55. is_minimal :: [FD] -> Bool
  56. is_minimal basis = undefined
  57.  
  58. -- 3.2.8절 Algorithm 3.12
  59. project_FDs :: [Attr] -> [FD] -> [Attr] -> [FD]
  60. project_FDs as fds as1 = undefined
  61.  
  62.  
  63. -- the main function for running test examples
  64. main = do
  65. putStrLn "== Example 3.8 for closure test ============================="
  66. let fds = [ (["A","B"],["C"]),
  67. (["B","C"],["A","D"]),
  68. (["D"],["E"]),
  69. (["C","F"],["B"]) ]
  70. let xs = ["A","B"]
  71. putStrLn $ "S = " ++ showFDs fds
  72. putStrLn $ showAttrSet xs ++ "+ = " ++ showAttrSet (closure fds xs)
  73.  
  74. let fds_1 = [ (["A"],["D"]),
  75. (["B","C"],["A","D"]),
  76. (["F", "G"],["H"]),
  77. (["C","F"],["B"]) ]
  78. let xs_1 = ["A","D"]
  79. putStrLn $ "S = " ++ showFDs fds_1
  80. putStrLn $ showAttrSet xs_1 ++ "+ = " ++ showAttrSet (closure fds xs_1)
  81. --
  82.  
  83. putStrLn "== Example ... for is_derived_from test ====================="
  84.  
  85. let fds2 = [ (["A"], ["C"])
  86. , (["C"], ["D"])
  87. , (["C","F"], ["G"]) ]
  88. let fd_test1 = (["A"], ["D"])
  89. let fd_test2 = (["A"], ["G"])
  90. putStrLn $ "S = " ++ showFDs fds2
  91. putStrLn $ "A -> D is derived from S : " ++ show (is_derived_from fd_test1 fds2)
  92. putStrLn $ "A -> G is derived from S : " ++ show (is_derived_from fd_test2 fds2)
  93.  
  94.  
  95. let fds2_2 = [ (["A"], ["D"])
  96. , (["D"], ["G"])
  97. , (["C"], ["F"]) ]
  98. let fd_test1_1 = (["A"], ["F"])
  99. let fd_test2_2 = (["D"], ["G"])
  100. putStrLn $ "S = " ++ showFDs fds2_2
  101. putStrLn $ "A -> F is derived from S : " ++ show (is_derived_from fd_test1_1 fds2_2)
  102. putStrLn $ "D -> G is derived from S : " ++ show (is_derived_from fd_test2_2 fds2_2)
  103.  
  104.  
  105. --
  106. putStrLn "== Example ... for is_basis_of test ========================="
  107.  
  108. let s_fds = [ (["A"], ["B"]), (["B"], ["C"]), (["C"], ["D"]) ]
  109. let b_basis = [ (["A"], ["B"]), (["B"], ["C"]), (["C"], ["D"]) ]
  110.  
  111. putStrLn $ "S = " ++ showFDs s_fds
  112. putStrLn $ "B = " ++ showFDs b_basis
  113. putStrLn $ "B is basis of S : " ++ show (is_basis_of b_basis s_fds)
  114.  
  115. let s_fds2 = [ (["A"], ["C"]), (["C"], ["D"]), (["D"], ["G"]) ]
  116. let b_basis2 = [ (["A","B"], ["E"]), (["G"], ["A"]) ]
  117. putStrLn $ "S = " ++ showFDs s_fds2
  118. putStrLn $ "B = " ++ showFDs b_basis2
  119. putStrLn $ "B is basis of S : " ++ show (is_basis_of b_basis2 s_fds2)
  120.  
  121. let s_fds3 = [ (["A", "B"], ["C"]), (["C"], ["D"]), (["D"], ["G"]) ]
  122. let b_basis3 = [ (["A","B"], ["C"]), (["C"], ["D"]), (["D"], ["G"]) ]
  123. putStrLn $ "S = " ++ showFDs s_fds3
  124. putStrLn $ "B = " ++ showFDs b_basis3
  125. putStrLn $ "B is basis of S : " ++ show (is_basis_of b_basis3 s_fds3)
  126. --
  127.  
  128.  
  129. putStrLn "== Example ... for is_minimal test =========================="
  130. putStrLn "B = { ..->., ..->., ... }"
  131. putStrLn "B is minimal : True/False"
  132. --
  133. putStrLn "== Example ... for project_FDs test ========================="
  134. putStrLn "L = {......}"
  135. putStrLn "S = { ..->.., ..->.., ... ... ... }"
  136. putStrLn "L1 = {...}"
  137. putStrLn "S1 = { ..->.., ..->.., ... ... }"
  138. --
  139.  
  140. -- helper functions for pretty printing
  141. showFD :: FD -> String
  142. showFD (as,bs) = concat $ intersperse " " (as ++ "->" : bs)
  143.  
  144. showFDs :: [FD] -> String
  145. showFDs fds = "{" ++ concat (intersperse ", " $ map showFD fds) ++ "}"
  146.  
  147. showAttrSet :: [Attr] -> String
  148. showAttrSet as = "{" ++ concat (intersperse "," as) ++ "}"
  149.  
Success #stdin #stdout 0.01s 5320KB
stdin

stdout
== Example 3.8 for closure test =============================
S = {A B -> C, B C -> A D, D -> E, C F -> B}
{A,B}+ = {A,B,C,D,E}

S = {A -> D, B C -> A D, F G -> H, C F -> B}
{A,D}+ = {A,D,E}

== Example ... for is_derived_from test =====================
S = {A -> C, C -> D, C F -> G}
A -> D is derived from S : True
A -> G is derived from S : False

S = {A -> D, D -> G, C -> F}
A -> F is derived from S : False
D -> G is derived from S : True

== Example ... for is_basis_of test =========================
S = {A -> B, B -> C, C -> D}
B = {A -> B, B -> C, C -> D}
B is basis of S : True

S = {A -> C, C -> D, D -> G}
B = {A B -> E, G -> A}
B is basis of S : False

S = {A B -> C, C -> D, D -> G}
B = {A B -> C, C -> D, D -> G}
B is basis of S : True

== Example ... for is_minimal test ==========================
B = { ..->., ..->., ... }
B is minimal : True/False

== Example ... for project_FDs test =========================
L = {......}
S = { ..->.., ..->.., ... ... ... }
L1 = {...}
S1 = { ..->.., ..->.., ... ... }