Commit 176aeacb authored by Hemery Mathieu's avatar Hemery Mathieu
Browse files

Improve remove fraction for verbose models

parent 5727c048
......@@ -1317,8 +1317,12 @@ ode_add_expression_to_molecule(NewExpression, Molecule) :-
% denominator
remove_fraction(_ListVar, d( X )/dt = Expr, d( X )/dt = NewExpr) :-
find_common_denominator(Expr, Denominator),
debug(remove_fraction, "~w' = ~w~n", [X, Expr]),
find_common_denominator(Expr, DenominatorTempo),
avoid_duplicate(DenominatorTempo, Denominator),
debug(remove_fraction, "Den -> ~w~n", [Denominator]),
multiply_each_term(Expr, Denominator, Expr2),
debug(remove_fraction, "Deriv. -> ~w~n", [Expr2]),
simplify(Expr2, NewExpr).
......@@ -1327,34 +1331,57 @@ remove_fraction(_ListVar, d( X )/dt = Expr, d( X )/dt = NewExpr) :-
% list all the denominator present in Expr, ListVariable is given as context in order to
% be able to skip parameters
find_common_denominator(Expr + _Num/Den, [Den|Tail]) :-
find_common_denominator(Expr1 + Expr2, Den12) :-
!,
find_common_denominator(Expr, Tail).
find_common_denominator(Expr1, Den1),
find_common_denominator(Expr2, Den2),
ord_union(Den1, Den2, Den12).
find_common_denominator(Expr + _Num, Tail) :-
find_common_denominator(_Term/Expr, Den) :-
!,
find_common_denominator(Expr, Tail).
forge_denominator(Expr, DenRaw),
list_to_ord_set(DenRaw, Den).
find_common_denominator(_Term/Den, [Den]) :- !.
find_common_denominator(_Term, []).
forge_denominator(Expr*A, [A|Tail]) :- !,
forge_denominator(Expr, Tail).
forge_denominator(Expr, [Expr]).
avoid_duplicate(L, A) :- avoid_duplicate(L, L, A).
avoid_duplicate([], _List, []).
avoid_duplicate([Head|Tail1], List, [Head|Tail2]) :-
\+((
Head = Term^N
->
member(Term^NN, List),
NN > N
;
member(Head^N, List),
N > 1
)),!,
avoid_duplicate(Tail1, List, Tail2).
avoid_duplicate([_Head|Tail1], List, Tail2) :-
avoid_duplicate(Tail1, List, Tail2).
%! multiply_each_term(+Expr, +ListDenominator, -NexExpr)
%
%
multiply_each_term(Expr + Head, Denominator, NewExpr + NewHead) :-
multiply_each_term(Expr1 + Expr2, Denominator, NewExpr1 + NewExpr2) :-
!,
multiply_term(Head, Denominator, NewHead),
multiply_each_term(Expr, Denominator, NewExpr).
multiply_each_term(Expr1, Denominator, NewExpr1),
multiply_each_term(Expr2, Denominator, NewExpr2).
multiply_each_term(Expr, Denominator, NewExpr) :-
!,
multiply_term(Expr, Denominator, NewExpr).
multiply_term(Num/Den, Denominator, NewNum) :-
multiply_term(Num/DenRaw, Denominator, NewNum) :-
!,
subtract(Denominator, [Den], ToMult),
forge_denominator(DenRaw, Den),
subtract(Denominator, Den, ToMult),
mult_by(Num, ToMult, NewNum).
multiply_term(Num, Denominator, NewNum) :-
......
......@@ -101,7 +101,7 @@ test(
remove_fraction([a], d(a)/dt = a/b, d(a)/dt = a),
remove_fraction([a], d(a)/dt = a/(b+c) + d, d(a)/dt = a + d*b + d*c),
remove_fraction([a], d(a)/dt = a/(b+c) + -1*d, d(a)/dt = a - d*b - d*c),
remove_fraction([a], d(a)/dt = a/b + c/d + e, d(a)/dt = a*d + c*b + e*b*d),
remove_fraction([a], d(a)/dt = a/b + c/d + e, d(a)/dt = a*d + c*b + e*d*b),
remove_fraction([a], d(a)/dt = a/b + c/d, d(a)/dt = a*d + c*b).
test(
......@@ -120,7 +120,7 @@ test(
normalize_ode([d(x)/dt=k7/1+ - (k8*x)/1+ - (k9*x)/(x+k1)], [x])
)).
test('is_polynomial', []) :-
test('is_polynomial', [nondet]) :-
clear_model,
%Ensure that a, b and c are recognized as molecules
add_ode([d(a)/dt = 1, d(b)/dt = 1, d(c)/dt = 1]),
......
Supports Markdown
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