@@ -345,3 +345,34 @@ fn test_real_approx() {
345345 assert_eq ! ( res. approx_f64( ) , res. approx( 32 ) . parse( ) . unwrap( ) ) ;
346346 assert_ne ! ( res. approx_f64( ) , res. approx( 16 ) . parse( ) . unwrap( ) ) ;
347347}
348+
349+ #[ test]
350+ fn test_real_exact ( ) {
351+ let ctx = Context :: new ( & Config :: default ( ) ) ;
352+ let x = Real :: new_const ( & ctx, "x" ) ;
353+ let y = Real :: new_const ( & ctx, "y" ) ;
354+ let z = Real :: new_const ( & ctx, "z" ) ;
355+ let a = Real :: new_const ( & ctx, "a" ) ;
356+ let xx = & x * & x;
357+ let zero = Real :: from_real ( & ctx, 0 , 1 ) ;
358+ let two = Real :: from_real ( & ctx, 2 , 1 ) ;
359+ let s = Solver :: new ( & ctx) ;
360+ s. assert ( & x. ge ( & zero) ) ;
361+ s. assert ( & xx. _eq ( & two) ) ;
362+ s. assert ( & y. _eq ( & Int :: from_i64 ( & ctx, 5 ) . to_real ( ) ) ) ;
363+ s. assert ( & z. _eq ( & Real :: from_real ( & ctx, 1 , 2 ) ) ) ;
364+ s. assert ( & a. _eq ( & Real :: from_real ( & ctx, 1 , i32:: MAX - 90 ) ) ) ;
365+ assert_eq ! ( s. check( ) , SatResult :: Sat ) ;
366+ let m = s. get_model ( ) . unwrap ( ) ;
367+ let res_x = m. eval ( & x, false ) . unwrap ( ) ;
368+ let res_y = m. eval ( & y, false ) . unwrap ( ) ;
369+ let res_z = m. eval ( & z, false ) . unwrap ( ) ;
370+ let res_a = m. eval ( & a, false ) . unwrap ( ) ;
371+ assert_eq ! ( res_x. exact_f64( ) , None ) ; // sqrt is irrational
372+ println ! ( "{:?}" , res_y. exact_f64( ) ) ;
373+ assert_eq ! ( res_y. exact_f64( ) , Some ( 5.0 ) ) ;
374+ println ! ( "{:?}" , res_z. exact_f64( ) ) ;
375+ assert_eq ! ( res_z. exact_f64( ) , Some ( 0.5 ) ) ;
376+ println ! ( "{:?}" , res_a. exact_f64( ) ) ;
377+ assert_eq ! ( res_a. exact_f64( ) , Some ( 1 as f64 / ( i32 :: MAX - 90 ) as f64 ) ) ;
378+ }
0 commit comments