Advertisement
JoelSjogren

Untitled

Mar 19th, 2021
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.01 KB | None | 0 0
  1. {-# LANGUAGE FlexibleInstances #-}
  2. import Data.Set (Set,elems,cartesianProduct,fromList,empty,insert,singleton,
  3. union,unions,difference,filter)
  4.  
  5. -- Fix a natural number n, and identify it with the ordinal {0 < ... < n}. Let A be the set of binary relations R on n that satisfy (A1) if R(a, b) then a <= b, (A2) R is reflexive, (A3) R is transitive. Let B be the set of binary relations S on n that satisfy (B1) if S(a, b) then a + b <= n, (B2) S is downward-closed. Count the elements of A and B depending on n.
  6.  
  7. class Below a where
  8. below :: a -> Set a
  9.  
  10. instance (Below a, Below b) => Below (a, b) where
  11. below (a,b) = cartesianProduct (below a) (below b)
  12.  
  13. type N = Integer
  14.  
  15. instance Below N where
  16. below n = fromList [0..n]
  17.  
  18. data CombinatorialProblem a = CP
  19. {
  20. bound :: Set a,
  21. close :: Set a -> Set a
  22. }
  23.  
  24. enumerate :: Ord a => CombinatorialProblem a -> Set (Set a)
  25. enumerate cp = iterate' f null (empty, singleton (close cp empty))
  26. where
  27. f (old, new) = (pretty_old, pretty_new)
  28. where
  29. pretty_old = union old new
  30. fresh = [close cp (insert a s) | a <- elems (bound cp), s <- elems new]
  31. pretty_new = fromList fresh `difference` pretty_old
  32.  
  33. iterate' :: ((a,a) -> (a,a)) -> (a -> Bool) -> (a,a) -> a
  34. iterate' f p x = let (x0,x1) = iterate'' x in x0
  35. where
  36. iterate'' x = if p (let (x0,x1) = x in x1) then x else iterate'' (f x)
  37.  
  38. count :: Ord a => CombinatorialProblem a -> Int
  39. count cp = length (enumerate cp)
  40.  
  41.  
  42. -- PROBLEM B --
  43.  
  44. downwardClosed :: (Below a, Ord a) => a -> CombinatorialProblem a
  45. downwardClosed a = CP (below a) down
  46. where
  47. down s = unions [below n | n <- elems s]
  48.  
  49. downwardClosedTriangle :: N -> CombinatorialProblem (N,N)
  50. downwardClosedTriangle n = CP bound' (close $ downwardClosed (n,n))
  51. where
  52. bound' = Data.Set.filter (\(i,j) -> i+j<=n) (bound $ downwardClosed (n,n))
  53.  
  54. {-
  55. λ> count . downwardClosed . (\a -> (a,a)) <$> [0..6]
  56. [2,6,20,70,252,924,3432]
  57. OEIS A000984, Central binomial coefficients
  58. (n+1 times as many as the one below, but shifted once)
  59.  
  60. λ> count . downwardClosedTriangle <$> [0..4]
  61. [2,5,14,42,132]
  62. OEIS A000108, Catalan numbers
  63. -}
  64.  
  65.  
  66. -- PROBLEM A --
  67.  
  68. reflexiveTransitive :: (Below a, Ord a) => a -> CombinatorialProblem (a,a)
  69. reflexiveTransitive a = CP (below (a,a)) (fix free)
  70. where
  71. free s = unions [refl,s,trans]
  72. where
  73. refl = fromList [(i,i) | i <- elems (below a)]
  74. trans = fromList [(i,k) | (i,j) <- elems s, (j',k) <- elems s, j == j']
  75.  
  76. fix :: Eq a => (a -> a) -> a -> a
  77. fix f x = let x' = f x in if x == x' then x else fix f x'
  78.  
  79. reflexiveTransitiveTriangle :: N -> CombinatorialProblem (N,N)
  80. reflexiveTransitiveTriangle n = CP bound' (close $ reflexiveTransitive n)
  81. where
  82. bound' = Data.Set.filter (\(i,j) -> i<=j) (bound $ reflexiveTransitive n)
  83.  
  84. main = return ()
  85.  
  86. {-
  87. λ> count . reflexiveTransitive <$> [0..4]
  88. [1,4,29,355,6942]
  89. A000798
  90.  
  91. λ> count . reflexiveTransitiveTriangle <$> [0..6]
  92. [1,2,7,40,357,4824,96428]
  93. OEIS A006455
  94. -}
  95.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement