% rationals, .... % this is less than the least efficient implementation % rationals_division/3, rationals_add_list/2, % rationals_addition/3, rationals_cutoff/2, rationals_is_rat/2. % rationals_hyphened_product_sum_list/4, rationals_multiplication/3. % Should have two version for the operations, % one with and one without simlification, % agrregates calling the not simplifying operation. rationals_division( NomNom/NomDnm, DnmNom/DnmDnm, Simplified ) :- ResNom is NomNom * DnmDnm, ResDnm is NomDnm * DnmNom, rationals_simplify( ResNom/ResDnm, Simplified ). rationals_multiplication( Nom1/Dnm1, Nom2/Dnm2, Simplified ) :- ResNom is Nom1 * Nom2, ResDnm is Dnm1 * Dnm2, rationals_simplify( ResNom/ResDnm, Simplified ). rationals_addition( LNom/LDnm, RNom/RDnm, Simplified ) :- rationals_lcd_factors( LDnm, RDnm, ResDnm, LFctr, RFctr ), ResNom is LNom * LFctr + RNom * RFctr, % maybe there is something simpler in this case. rationals_simplify( ResNom/ResDnm, Simplified ). rationals_subtraction( LNom/LDnm, RNom/RDnm, ResNom / ResDnm ) :- rationals_lcd_factors( LDnm, RDnm, ResDnm, LFctr, RFctr ), ResNom is LNom * LFctr - RNom * RFctr. % rationals_sign_normalise( ResNom, ResDnm, Quotient ). rationals_sign_normalise( Nom, Dnm, Quotient ) :- ( Dnm < 0 -> ( Nom < 0 -> AbsNom is abs(Nom), AbsDnm is abs(Dnm), Quotient = AbsNom / AbsDnm ; AbsDnm is abs(Dnm), Quotient = ( - Nom / AbsDnm ) ) ; Quotient = Nom / Dnm ). rationals_subtract_list_from( [], _This, [] ). rationals_subtract_list_from( [H|T], This, [SH|ST] ) :- % rationals_subtraction( H, This, SH ), rationals_subtraction( This, H, SH ), rationals_subtract_list_from( T, This, ST ). % rationals_all_multiply_list( [], _Nom/_Dnm, [] ). rationals_all_multiply_list( [], _Mult, [] ). rationals_all_multiply_list( [H|T], Multi, [MTH|MsTT] ) :- rationals_multiplication( H, Multi, MTH ), rationals_all_multiply_list( T, Multi, MsTT ). rationals_add_list( [], 0/1 ). % double check that this is ok rationals_add_list( [H|T], Res ) :- rationals_add_list( T, H, Res ). rationals_add_list( [], Ans, Ans ). % rationals_simplify( Ans, Simplified ). rationals_add_list( [H|T], Acc, Res ) :- rationals_addition( H, Acc, NewAcc ), rationals_add_list( T, NewAcc, Res ). rationals_multiplication_list( List, Result ) :- rationals_multiplication_list( List, 1/1, Result ). rationals_multiplication_list( [], Acc, Acc ). rationals_multiplication_list( [H|T], Acc, Res ) :- rationals_multiplication( Acc, H, NewAcc ), rationals_multiplication_list( T, NewAcc, Res ). rationals_lcd_factors( NatOne, NatTwo, LCD, OneFact, TwoFact ) :- gcd( NatOne, NatTwo, GCD ), % GCD is gcd( NatOne, NatTwo ), OneFact is NatTwo // GCD, TwoFact is NatOne // GCD, LCD is OneFact * TwoFact * GCD. rationals_hyphened_product_sum_list( HList, LList, RList, PrSum ) :- rationals_hyphened_product_sum_list_1( HList, 0/1, LList, RList, PrSum ). rationals_hyphened_product_sum_list_1( [LH-RH|T], Acc, [LH|LT], [RH|RT], PS ) :- rationals_multiplication( LH, RH, Product ), rationals_addition( Product, Acc, NewAcc ), rationals_hyphened_product_sum_list_1( T, NewAcc, LT, RT, PS ). rationals_hyphened_product_sum_list_1( [], Res, [], [], Res ). rationals_cutoff( excl(Numb1), Numb2 ) :- !, rationals_cutoff_1( Numb1, Numb2, excl ). rationals_cutoff( incl(Numb1), Numb2 ) :- !, rationals_cutoff_1( Numb1, Numb2, incl ). rationals_cutoff( Numb1, Numb2 ) :- rationals_cutoff_1( Numb1, Numb2, incl ). rationals_cutoff_1( MayRat1, MayRat2, ExInCl ) :- rationals_is_rat( MayRat1, Nom1/Den1 ), rationals_is_rat( MayRat2, Nom2/Den2 ), FactNom is Nom1 * Den2, FactDen is Den1 * Nom2, ( FactNom > FactDen -> true ; rationals_cutoff_eq( ExInCl, FactNom, FactDen ) ). rationals_cutoff_eq( incl, Fact, Fact ). rationals_is_rat( Var, Var ) :- var(Var),!. rationals_is_rat( Nom/Den, Nom/Den ) :- !. rationals_is_rat( 0, 0/1 ) :- !. rationals_is_rat( 1, 1/1 ). rationals_for_comp( Nm1/Dn1, Nm2/Dn2, Int1, Int2 ) :- Int1 is Nm1 * Dn2, Int2 is Nm2 * Dn1. rationals_simplify( Nom/Dnm, SNom/SDnm ) :- gcd( Nom, Dnm, Gcd ), % Gcd is gcd( Nom, Dnm ), SNom is Nom // Gcd, SDnm is Dnm // Gcd. % rationals_iinv( Nom/Dnm, 1/Dnm % rationals_abs_list % assume negative Rats have sign at the Nominator. % no Rat is allowed with negative signs on both the % Nominator and Denominator. % rationals_abs_list( [], [] ). rationals_abs_list( [Nom/Dnm|T], [AbsH|AbsT] ) :- ( Nom =< 0 -> AbsNom is abs(Nom), AbsH = AbsNom / Dnm ; AbsH = Nom / Dnm ), rationals_abs_list( T, AbsT ). rationals_integer_to( Int, Int/1 ). % rationals_invertion( [], [] ). rationals_invert( Nom/Dnm, NNm/NDm ) :- ( Nom > 0 -> NNm = Dnm, NDm = Nom ; ( Nom = 0 -> write( error(division_by_zero,rationals_invert/2) ), nl, abort ; NNm = - Dnm, NDm = Nom ) ). gcd( M, N, C ) :- ( N =:= 0 -> C is M ; NewN is M mod N, gcd( N, NewN, C ) ). is_only_rational( Rat, Goal, ArgNo ) :- ( var(Rat) -> print_message( error, domain_error(Goal,ArgNo,rational-(var(Rat)),Rat) ) ; (Rat = _Nmn/_Dnm -> true ; % fixme: first Rat was IntP/IntQ print_message( error, domain_error(Goal,ArgNo,rational-(Rat),Rat) ) ) ). % probability_measure_constraint( Constr, MethPrbs, ConstrProb, Measrs ) :- rationals_to_probabilities( Rats, Probs ) :- rationals_add_list( Rats, Sum ), rationals_invert( Sum, MUs ), rationals_all_multiply_list( Rats, MUs, Probs ). rationals_prob_compliment( Prob, Compl ) :- rationals_subtraction( 1/1, Prob, Compl ). % is this obsolete ? measure_constraint( MethPrbs, ConstrProb, Measrs ) :- rationals_all_multiply_list( MethPrbs, ConstrProb, Measrs ). remove_divisors( [], _Product, [] ). remove_divisors( [H|T], Product, Ds ) :- ( Product mod H =:= 0 -> Ds = NxDs ; Ds = [H|NxDs] ), remove_divisors( T, Product, NxDs ). % :- ensure_loaded( 'System/Sicstus/maplist' ). % :- ensure_loaded( library(lists) ). rationals_rev_proxb( Rats, Revs ) :- % rationals_cons_lists( Rats, _Nms, Dns ), % maplist( rationals_cons_dnm, Rats, Dns ), rationals_lcm( Rats, Lcm ), maplist( rationals_factor_nom, Rats, NewNoms, [Lcm] ), % maybe slassh them within the thousand ? sum_list( NewNoms, Sum ), subtract_list_from( NewNoms, Sum, SubNoms ), sum_list( SubNoms, SubDnm ), rationals_cons_on_dnm( Revs, SubNoms, SubDnm ). % rationals_lcm( Rats, Lcm ) :- % max_list( Rats, _MaxRat ), % fail, % rationals_add_list( Rats, _Nom/Lcm ). rationals_factor_nom( Nom/Dnm, NewNom, NewDnm ) :- NewNom is Nom * ( Dnm // NewDnm ). rationals_cons( Nom/Dnm, Nom, Dnm ). rationals_cons_lists( [], [], [] ). rationals_cons_lists( [Nom/Dnm|TRats], [Nom|TNs], [Dnm|TDs] ) :- rationals_cons_lists( TRats, TNs, TDs ). rationals_cons_nom( Nom/_Dnm, Nom ). % to use with maplist/3. rationals_cons_dnm( _Nom/Dnm, Dnm ). rationals_cons_on_dnm( [], [], _Dnm ). rationals_cons_on_dnm( [HNom/Dnm|TRats], [HNom|TNom], Dnm ) :- rationals_cons_on_dnm( TRats, TNom, Dnm ). subtract_list_from( [], _Omni, [] ). subtract_list_from( [H|T], Omni, [DiffH|DiffT] ) :- DiffH is Omni - H, subtract_list_from( T, Omni, DiffT ). rationals_dilute( Nom / Dnm, DRat, Proportion ) :- abs(Nom) < Proportion, !, DRat = Nom / Dnm. rationals_dilute( Nom / Dnm, FRat, Proportion ) :- DiN is Nom // Proportion, DiD is Dnm // Proportion, % write( diluting(Nom / Dnm, to(DiN / DiD)) ), nl, rationals_dilute( DiN / DiD, FRat, Proportion ). rationals_to_aprox_int( Nom / Dnm, ComDnm, ApxInt ) :- % ApxInt is floor( (ComDnm / Dnm) * Nom ). ApxInt is (ComDnm * Nom) // Dnm. rationals_inflate( Nom / Dnm, Inflator, Integer ) :- Integer is integer( Nom * (Inflator / Dnm) ). rationals_sort( [], [] ). rationals_sort( [H|T], Sort ) :- rationals_sort( T, [H], Sort ). rationals_sort( [], Sort, Sort ). rationals_sort( [H|T], Acc, Sort ) :- rationals_insert( Acc, H, NxAcc ), rationals_sort( T, NxAcc, Sort ). rationals_insert( [], Elem, [Elem] ). rationals_insert( [H|T], Elem, Insert ) :- ( Elem < H -> Insert = [Elem,H|T] ; Insert = [H|Tinsert], rationals_insert( T, Elem, Tinsert ) ).