content: module Trit (Trit, rationalToTrit, getIntegral, getFraction, getFraction',
  		neg, addTrits, subTrits, shiftLeft, shiftRight, multiply
  		) where
  
  import Stream
  import Utilities
  import Data.Ratio
  
  type Mantissa = Stream
  type Fraction = Stream
  type Trit     = (Mantissa, Fraction)
  
  
  -- Convert from a Rational number to its Trit representation (Integral, Fraction)
  rationalToTrit :: Rational -> Trit
  rationalToTrit x
  		|x<1		= ([0], rationalToStream x)
  		|otherwise	= (u', rationalToStream v)
  		where   u = n `div` d
  			u' = toBinary u
  	      		v = x - (toRational u)
  			n = numerator x
  	      		d = denominator x
  			
  			
  -- Get the integral part of Trit
  getIntegral :: Trit -> Mantissa
  getIntegral = fst
  
  
  
  -- Get the fraction part of Trit, with n digit of the stream
  getFraction :: Int -> Trit -> Stream
  getFraction n = take n. snd
  
  
  -- Get the fraction part of Trit
  getFraction' :: Trit -> Stream
  getFraction' = snd
  
  
  
  -- Negate a Trit
  neg :: Trit -> Trit
  neg (a, b) = (negate' a, negate' b)
  
  
  
  -- Add two Trits
  addTrits :: Trit -> Trit -> Trit
  addTrits (m1, (x1:x2:xs)) (m2, (y1:y2:ys)) = (u,addStream (x1:x2:xs) (y1:y2:ys))
  					   where u' = addFiniteStream m1 m2
  					         c = [carry x1 x2 y1 y2]
  						 u = addFiniteStream u' c
  
  
  
  -- Substraction of 2 Trits
  subTrits :: Trit -> Trit -> Trit
  subTrits x y = addTrits x (neg y)
  
  
  
  -- Shift left = *2 opertaion with Trit
  shiftLeft :: Trit -> Trit
  shiftLeft (x, (y:ys)) = (x++ [y], ys)
  
  
  -- Shift right = /2 operation with Trit
  shiftRight :: Trit -> Integer -> Trit
  shiftRight (x, xs) 1 = (init x, (u:xs))
  		    where u = last x
  shiftRight (x, xs) n = shiftRight (init x, (u:xs)) (n-1)
   		    where u = last x		    
  		  
  		  
  
  -- Multiply a Trit stream by 1,0 or -1, simply return the stream
  mulOneDigit :: Integer -> Stream -> Stream
  mulOneDigit x xs
                |x==1      = xs
  	      |x==0      = zero'
  	      |otherwise = negate' xs
  	      where zero' = (0:zero')
  
  
  
  
  
  
  -- Multiplication of two streams
  multiply :: Stream -> Stream -> Stream
  multiply (a0:a1:x) (b0:b1:y) = average p q
  			       where p = average (a1*b0: (average (mulOneDigit b1 x)
  							         (mulOneDigit a1 y)))
  					         (average (mulOneDigit b0 x)
  						          (mulOneDigit a0 y))
  				     q = (a0*b0:a0*b1:a1*b1:(multiply x y))
  
  
  
  
  start0 = take 30 (multiply (rationalToStream (1%2)) zo)
  
  zo :: Stream
  zo = 1:(-1):zero
       where zero = 0:zero
  
  start1 = take 30 (average (rationalToStream (1%2)) (negate' (rationalToStream (1%4))))
  
  	 
  	 
  