Commit dcef3978 by Mathieu Hemery

### Introduce the determine_boundary function (still buggy)

parent cf83205f
 ... ... @@ -7,6 +7,7 @@ always_negative/1, always_positive/1, determine_sign/2, determine_boundary/3, normalize_number/2, is_null/1, zero_like/1, ... ... @@ -19,6 +20,7 @@ :- use_module(doc). :- use_module(util). :- set_prolog_flag(float_overflow, infinity). :- dynamic(canonical/3). ... ... @@ -693,13 +695,93 @@ arithmetic_operation(_ ^ _). % Check if Expr is assure to be always negative/positive, fail if it can change sign % or if it is impossible to decide always_positive(Expr) :- determine_boundary(Expr, I, _U), I >= 0. always_negative(Expr) :- determine_sign(Expr, zero); determine_sign(Expr, neg). determine_boundary(Expr, _I, U), U =< 0. always_positive(Expr) :- determine_sign(Expr, zero); determine_sign(Expr, pos). %always_negative(Expr) :- % determine_sign(Expr, zero); % determine_sign(Expr, neg). % %always_positive(Expr) :- % determine_sign(Expr, zero); % determine_sign(Expr, pos). %! determine_boundary(+Expr, -Up, -Down) % % Try to evaluate the boundary of an expression determine_boundary(X, N, N) :- is_numeric(X, N), !. determine_boundary(X, 0, 1.0Inf) :- atom(X), !. determine_boundary(A+B, IAB, UAB) :- determine_boundary(A, IA, UA), determine_boundary(B, IB, UB), IAB is IA+IB, UAB is UA+UB. determine_boundary(A-B, IAB, UAB) :- determine_boundary(A, IA, UA), determine_boundary(B, IB, UB), IAB is IA-UB, UAB is UA-IB. determine_boundary(-A, ImA, UmA) :- determine_boundary(A, IA, UA), ImA is -UA, UmA is -IA. determine_boundary(A*B, IAB, UAB) :- determine_boundary(A, IA, UA), determine_boundary(B, IB, UB), ((IA=0; IB=0) -> T1 = 0; T1 is IA*IB), ((UA=0; IB=0) -> T2 = 0; T2 is UA*IB), ((IA=0; UB=0) -> T3 = 0; T3 is IA*UB), ((UA=0; UB=0) -> T4 = 0; T4 is UA*UB), min_list([T1, T2, T3, T4], IAB), max_list([T1, T2, T3, T4], UAB). determine_boundary(A/B, IAB, UAB) :- determine_boundary(A, IA, UA), determine_boundary(B, IB, UB), ((IB =:= inf; IB =:= -inf) -> T1 = 0; T1 is IA/IB), ((UB =:= inf; UB =:= -inf) -> T2 = 0; T2 is IA/UB), ((IB =:= inf; IB =:= -inf) -> T3 = 0; T3 is UA/IB), ((UB =:= inf; UB =:= -inf) -> T4 = 0; T4 is UA/UB), min_list([T1, T2, T3, T4], IAB), max_list([T1, T2, T3, T4], UAB). determine_boundary(A^N, IAB, UAB) :- determine_boundary(A, IA, UA), is_numeric(N, NN), ( NN > 0 -> IAB is IA^NN, UAB is UA^NN ; IAB is UA^NN, UAB is IA^NN ). determine_boundary(exp(A), IAB, UAB) :- determine_boundary(A, IA, UA), IAB is exp(IA), UAB is exp(UA). determine_boundary(sin(_X), -1, 1). determine_boundary(cos(_X), -1, 1). %! determine_sign(+Expr, -Sign) ... ...
 ... ... @@ -23,6 +23,15 @@ test('determine_sign', []) :- determine_sign((x-1)^k1, pos), determine_sign((x-1)^k2, dnk). test('always_positive_negative', []) :- parameter([k1 = 2, k2 = 3]), always_positive((a+1)^2), always_negative(-exp(a)), always_positive(a/(a+1)), always_positive((2+a)*0), always_negative((2+a)*0), always_positive((x-1)^k1), true. test('is_null', []) :- is_null(a*0*1/2), ... ...
 ... ... @@ -49,6 +49,7 @@ test('test_wf_reactant', []) :- test('test_wf_inhibitor', []) :- with_output_to(atom(_), ( parameter([k=1, n=2, k100=10]), test_wf_inhibitor(a, b/(1+a)), test_wf_inhibitor(a, b/(k+a)^2), test_wf_inhibitor(c1, v10*t3^n/(k100^n+t3^n+c1^n)), ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment