さかい #6231(2008/04/29 09:22 GMT) [ Haskell ] Rating1/1=1.00
see: 有限体GF(p) - ヒビルテ (2005-07-19)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-} module GF ( Z , S , Nat , Prime , GF , GF2 , GF3 , GF5 --, gf ) where import Data.Ratio (denominator, numerator) --import Language.Haskell.TH ----------------------------------------------------------------------------- data Z data S n newtype NatInt n = NatInt Int class Nat n where natInt :: NatInt n instance Nat Z where natInt = NatInt 0 instance Nat n => Nat (S n) where natInt = case (natInt :: NatInt n) of NatInt n -> NatInt (n+1) ----------------------------------------------------------------------------- class Nat n => Prime n instance (Nat n, PrimeTest (S (S n)) (S (S n))) => Prime (S (S n)) -- p は {x | 1<x<a} では割り切れない -- 実装は手抜き class PrimeTest p a instance PrimeTest p (S (S Z)) instance (PrimeTest p (S (S a)), NotDivide (S (S a)) p) => PrimeTest p (S (S (S a))) -- aはbを割り切らない class NotDivide a b instance NotDivide' a a b => NotDivide a b class NotDivide' a x y instance NotDivide' (S a) (S y) Z instance NotDivide' (S a) a y => NotDivide' (S a) Z (S y) instance NotDivide' (S a) x y => NotDivide' (S a) (S x) (S y) ----------------------------------------------------------------------------- newtype GF p = GF Int deriving Eq fromInt :: forall p. Nat p => Int -> GF p fromInt a = case (natInt :: NatInt p) of NatInt p -> GF (a `mod` p) toInt :: GF p -> Int toInt (GF x) = x instance Nat p => Show (GF p) where showsPrec n (GF x) = showsPrec n x instance Nat p => Read (GF p) where readsPrec n s = [(fromInt a, s') | (a,s') <- readsPrec n s] instance Nat p => Num (GF p) where GF a + GF b = fromInt $ a+b GF a * GF b = fromInt $ a*b GF a - GF b = fromInt $ a-b negate (GF a) = fromInt $ negate a abs a = a signum _ = 1 fromInteger = fromInt . fromIntegral instance Nat p => Ord (GF p) where GF a `compare` GF b = a `compare` b GF a `max` GF b = GF (a `max` b) GF a `min` GF b = GF (a `min` b) instance Nat p => Bounded (GF p) where minBound = 0 maxBound = case (natInt :: NatInt p) of NatInt p -> GF (p - 1) instance Nat p => Real (GF p) where toRational (GF x) = toRational x instance Prime p => Fractional (GF p) where fromRational r = fromInteger (numerator r) / fromInteger (denominator r) _ / 0 = error "divide by zero" (GF x) / (GF y) = case (natInt :: NatInt p) of NatInt p -> case exGCD y p of (a,_,_) -> fromInt (a*x) -- 拡張ユークリッド互除法 exGCD :: Int -> Int -> (Int,Int,Int) exGCD x y = loop x y 1 0 0 1 where loop x y a0 a1 b0 b1 | y == 0 = (a0,b0,x) | otherwise = loop y r a1 (a0 - q*a1) b1 (b0 - q*b1) where (q,r) = x `divMod` y instance Nat p => Enum (GF p) where toEnum x | toInt (minBound :: GF p) <= x && x <= toInt (maxBound :: GF p) = fromInt x | otherwise = error "GF.toEnum: bad argument" fromEnum (GF x) = x ----------------------------------------------------------------------------- type GF2 = GF (S (S Z)) type GF3 = GF (S (S (S Z))) type GF5 = GF (S (S (S (S (S Z))))) ----------------------------------------------------------------------------- {- gf :: Int -> Type gf x = AppT (ConT (mkName "GF.GF")) (f x) where f 0 = ConT (mkName "GF.Z") f (x+1) = AppT (ConT (mkName "GF.S")) (f x) -} -----------------------------------------------------------------------------
Rating1/1=1.00-0+
[ reply ]
さかい #6231() [ Haskell ] Rating1/1=1.00
see: 有限体GF(p) - ヒビルテ (2005-07-19)
Rating1/1=1.00-0+