%export real trit small_real small_real_digit plus small_plus %include "~ids/misc/lib/miralib/stdenv.def" || USER-LEVEL TYPE DECLARATIONS real ::= [trit] $POINT [trit] || before point is in ascending order, finite; after point || is in descending order, infinite || eg, in decimal, 37.46 would be [7,3] $POINT [4,6,0,0,0,.....] || see Grue's paper for further details trit == num || {-1,0,1} small_real == [small_real_digit] small_real_digit == num || {0,1,2} || USER-LEVEL FUNCTIONS plus :: real -> real -> real || not obvious from program structure! x $plus y = untwist (combine1 (x $newsum1 y)) where untwist (xi $TWISTED_POINT xf) = xi $POINT xf small_plus :: small_real -> small_real -> small_real || again, not obvious from syntax! x $small_plus y = ((x $sum1 y) $twisted_minus twisted_double carry_result) $twisted_plus twice_correct_to_mod_1 carry_result where carry_result = x $carry1 y || AUXILIARY TYPE DECLARATIONS twisted_real ::= [twisted_trit] $TWISTED_POINT [twisted_trit] twisted_trit == num || {-2,-1,0,1,2} twisted_small_real == [twisted_small_real_digit] twisted_small_real_digit == num || {-2,-1,0,1,2,3,4} || AUXILIARY FUNCTIONS twisted_plus :: small_real -> small_real -> twisted_small_real (xh:xt) $twisted_plus (yh:yt) = (xh+yh):(xt $twisted_plus yt) twisted_minus :: small_real -> small_real -> twisted_small_real (xh:xt) $twisted_minus (yh:yt) = (xh-yh):(xt $twisted_minus yt) twisted_double :: small_real -> twisted_small_real twisted_double = map (2*) twice_correct_to_mod_1 :: small_real -> small_real twice_correct_to_mod_1 = tl carry :: twisted_small_real -> small_real carry = map high_bit where high_bit d = iff (d<=1) then 0 else 1 sum0 :: small_real -> small_real -> twisted_small_real sum0 = twisted_plus carry0 :: small_real -> small_real -> small_real x $carry0 y = carry (x $sum0 y) sum1 :: small_real -> small_real -> twisted_small_real x $sum1 y = ((x $sum0 y) $twisted_minus twisted_double carry_result) $twisted_plus twice_correct_to_mod_1 carry_result where carry_result = x $carry0 y carry1 :: small_real -> small_real -> small_real x $carry1 y = carry (x $sum1 y) semihead :: [num] -> num semihead [] = 0 semihead (h:t) = h semitail :: [*] -> [*] semitail [] = [] semitail (h:t) = t semiattach :: num -> [num] -> [num] x $semiattach y = iff (x=0 & y=[]) then [] else (x:y) finiteplus :: [trit] -> [trit] -> [twisted_trit] x $finiteplus y = iff (x=[] & y=[]) then [] else ((semihead x + semihead y) $semiattach (semitail x $finiteplus semitail y) ) new_twisted_plus :: real -> real -> twisted_real (xi $POINT xf) $new_twisted_plus (yi $POINT yf) = (xi $finiteplus yi) $TWISTED_POINT (xf $twisted_plus yf) new_stay_twisted_plus :: twisted_real -> twisted_real -> twisted_real (xi $TWISTED_POINT xf) $new_stay_twisted_plus (yi $TWISTED_POINT yf) = (xi $finiteplus yi) $TWISTED_POINT (xf $twisted_plus yf) coord :: (twisted_trit -> twisted_trit) -> twisted_real -> twisted_real coord f (xi $TWISTED_POINT xf) = map f xi $TWISTED_POINT map f xf new_twisted_double_and_negate :: twisted_real -> twisted_real new_twisted_double_and_negate = coord ((-2)*) newtwice :: twisted_real -> twisted_real newtwice (xi $TWISTED_POINT (xfh:xft)) = (xfh:xi) $TWISTED_POINT xft combine :: twisted_real -> twisted_real -> twisted_real x $combine y = (x $new_stay_twisted_plus new_twisted_double_and_negate y) $new_stay_twisted_plus newtwice y combine0 :: twisted_real -> twisted_real combine0 x = x $combine coord detect_negative x where detect_negative d = iff (d<0) then (-1) else 0 newsum0 :: real -> real -> twisted_real newsum0 = new_twisted_plus newsum1 :: real -> real -> twisted_real x $newsum1 y = combine0 (x $newsum0 y) combine1 :: twisted_real -> twisted_real combine1 x = x $combine coord detect_positive x where detect_positive d = iff (d>0) then 1 else 0