Guest User

Untitled

a guest
Oct 19th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.46 KB | None | 0 0
  1.  
  2. import Data.Searchable
  3. import Control.Applicative
  4. import Data.Ratio
  5.  
  6. data Nat = Z | S Nat
  7. deriving (Ord, Show, Eq)
  8.  
  9. instance Num Nat where
  10. -- Functions defined in Kohlenbach p 45. These aren't the exact Kohlenbach definitions
  11. -- because the operations are *much* faster using this constructor order than using
  12. -- Kohlenbach's.
  13. Z + y = y
  14. S x + y = S (x+y)
  15. Z * y = Z
  16. S x * y = y + (x*y)
  17. x - Z = x
  18. x - S y = pd (x-y)
  19.  
  20. -- Additional items required by Num instance
  21. abs x = x
  22. signum Z = Z
  23. signum (S x) = S Z
  24. fromInteger 0 = Z
  25. fromInteger n = S . fromInteger $ n - 1
  26.  
  27. -- Additional functions defined in Kohlenbach p 45
  28. sg :: Nat -> Nat
  29. sg Z = 1
  30. sg (S x) = 0
  31.  
  32. pd Z = Z
  33. pd (S x) = x
  34.  
  35. -- least function, taken from Impossible Functional Programs. The (1 + n) is
  36. -- much faster than (n + 1) based on the way the S value constructor in + is ordered.
  37. least p = if p 0 then 0 else 1 + least(\n -> p (1 + n))
  38.  
  39. instance Fractional Nat where
  40. -- Use truncation for division on Nats. Use S value constructor for Div 0 protection.
  41. (/) x (S y) = least(\z -> (S z)*(S y) > x)
  42. fromRational r = (fromInteger . floor) r
  43.  
  44. -- Infinity declaration for testing totalness of predicates
  45. inf = S inf
  46.  
  47. -- Declaration of natural numbers for infinite search monad
  48. natural :: Set Nat
  49. natural = union (singleton Z) (S <$> natural)
  50.  
  51. -- A type to distinguish between true Nats and those used to encode a rational
  52. newtype QCode = QCode {unQCode :: Nat}
  53. deriving (Show)
  54.  
  55. -- Cantor pairing function (p 58)
  56. j :: Nat -> Nat -> QCode
  57. j x y = if k <= t then QCode k else QCode 0
  58. where k = least (\u -> 2*u == t)
  59. t = (x+y)*(x+y) + 3*x + y
  60.  
  61. -- Projection functions j1 and j2 for converting QCode back into first or second Nat argument (p 58)
  62. j1 :: QCode -> Nat
  63. j1 zq = least (\x -> x <= z && forsome natural (\y -> y <= z && unQCode(j x y) == z))
  64. where z = unQCode zq
  65.  
  66. j2 :: QCode -> Nat
  67. j2 zq = least (\y -> y <= z && forsome natural (\x -> x <= z && unQCode(j x y) == z))
  68. where z = unQCode zq
  69.  
  70. -- Even/Odd definitions for Nat
  71. evenNat :: Nat -> Bool
  72. evenNat n = (n/2)*2 == n
  73. oddNat = not . evenNat
  74.  
  75. -- Function for comparing two QCodes for equivalence (1/2 and 2/4 are equivalent rationals but have
  76. -- different QCodes)
  77. instance Eq QCode where
  78. (==) n1 n2 | evenNat j1n1 && evenNat j1n2 = (j1n1/2)*(j2n2 + 1) == (j1n2/2)*(j2n1 + 1)
  79. | oddNat j1n1 && oddNat j1n2 = ((j1n1+1)/2)*(j2n2 + 1) == ((j1n2+1)/2)*(j2n1 + 1)
  80. | otherwise = False
  81. where j1n1 = j1 n1
  82. j1n2 = j1 n2
  83. j2n1 = j2 n1
  84. j2n2 = j2 n2
  85.  
  86. -- Utility function for constructing a QCode from a numerator and denominator
  87. numden2QCode :: Integer -> Integer -> QCode
  88. numden2QCode num den | (num >= 0 && den > 0) || (num <= 0 && den < 0) = j (fromInteger $ 2*abs(num)) (fromInteger $ abs(den)-1)
  89. | otherwise = j (fromInteger $ 2*abs(num)-1) (fromInteger $ abs(den)-1)
  90.  
  91. -- Test out some QCode equivalence predicates
  92. main = do
  93. print $ numden2QCode (-1) 1 == numden2QCode (-2) 2 -- True
  94. print $ numden2QCode (-1) 1 == numden2QCode (-3) 3 -- True
  95. print $ numden2QCode (-1) 2 == numden2QCode 2 (-4) -- True
  96. print $ numden2QCode 1 2 == numden2QCode 2 4 -- True
  97. print $ numden2QCode 1 2 == numden2QCode 1 3 -- False
Add Comment
Please, Sign In to add comment