Commit 569495ee authored by SOLIMAN Sylvain's avatar SOLIMAN Sylvain

Merge branch 'release/4.4.15' into master

parents f54f3bb2 0abb1fea
......@@ -199,7 +199,7 @@ gadagne_restart: gadagne
ssh -t gadagne 'cd /opt/tmpnb/ && sudo ./cleanup.sh && sudo ./tmpnb_biocham.sh'
release:
echo "current version: " && grep '^version' about.pl
@echo "current version: " && grep '^version' about.pl
@read -p "Version number (e.g. 4.1.0): " version && \
git flow release start "$$version" && \
sed -i"" -e "s/^version('.*')/version('$$version')/" about.pl && \
......
......@@ -8,7 +8,7 @@
about/0
]).
version('4.4.14').
version('4.4.15').
copyright(
'Copyright (C) 2003-2020 Inria, EPI Lifeware, Saclay-Île de France, France'
......
......@@ -6,7 +6,9 @@
additive_normal_form/2,
always_negative/1,
always_positive/1,
normalize_number/2
normalize_number/2,
is_null/1,
modulo/3
]).
% Insert here for separate compilation and linting
......@@ -389,7 +391,7 @@ insert_coef(A, Coef, Result) :-
Coef > 0,
Coef < 1,
CoefInv is 1 / Coef,
0.0 is float_fractional_part(CoefInv)
0.0 =:= float_fractional_part(CoefInv)
->
normalize_number(CoefInv, CoefInvNorm),
Result = A / CoefInvNorm
......@@ -603,6 +605,13 @@ rewrite_distribute(A - (B + C), A - B - C).
rewrite_distribute(- (A + B), - A - B).
rewrite_distribute(A^1, A).
rewrite_distribute(A^N, A*A^Nm) :-
integer(N),
N > 1,
Nm is N-1.
additive_normal_form(In, Out) :-
rewrite(rewrite_additive_normal_form, In, Out).
......@@ -716,16 +725,17 @@ always_positive(A):- % assumed for concentrations, parameters
always_positive(- A) :-
always_negative(A).
always_positive(A ^ B) :-
always_positive(_A ^ B) :-
number(B),
(
0 is B mod 2
modulo(B, 2, 0)
->
true
;
always_positive(A)
).
always_positive(A ^ _B) :-
always_positive(A).
always_positive(A + B) :-
always_positive(A),
always_positive(B).
......@@ -753,6 +763,7 @@ always_positive(A / B) :-
always_negative(A),
always_negative(B).
always_positive(exp(_A)).
normalize_number(N, Norm) :-
(
......@@ -767,3 +778,33 @@ normalize_number(N, Norm) :-
;
Norm = N
).
%! is_null(+Expr)
%
% Check if an expression is uniformly null
is_null(Expr) :-
once(is_null_sr(Expr)).
is_null_sr(0).
is_null_sr(0.0).
is_null_sr(-A) :- is_null_sr(A).
is_null_sr(A*B) :- is_null_sr(A); is_null_sr(B).
is_null_sr(A/_B) :- is_null_sr(A).
is_null_sr(A+B) :- is_null_sr(A), is_null_sr(B).
is_null_sr(A-B) :- is_null_sr(A), is_null_sr(B).
is_null_sr(_A^(-_N)) :- !, false.
is_null_sr(A^_N) :- is_null_sr(A).
%! modulo(+A, +B)
%
% compute C is mod(A,B) but fail instead of raising an error when A or B are not integer
modulo(A, B, C) :-
catch(
C is mod(A, B),
error(type_error(integer,_N), _Context),
fail
).
......@@ -2,7 +2,15 @@
:- begin_tests(arithmetic_rules, [setup((clear_model, reset_options))]).
test('distribute', [true(Out == a * a + a * b + c)]) :-
test('distribute1', [true(Out == a * a + a * b + c)]) :-
distribute(a * (a + b) + c, Out).
test('distribute2', []) :-
distribute((a+b)^2, a*a+a*b+(b*a+b*b)),
distribute((a+b)^ -2, (a+b)^ -2).
test('is_null', []) :-
is_null(a*0*1/2),
\+(is_null(a*b/0)).
:- end_tests(arithmetic_rules).
FROM registry.gitlab.inria.fr/lifeware/biocham:v4.4.14
FROM registry.gitlab.inria.fr/lifeware/biocham:v4.4.15
{
"name": "gui",
"version": "4.4.14",
"version": "4.4.15",
"description": "biocham gui in jupyter notebook",
"main": "src/index.js",
"scripts": {
......
......@@ -24,12 +24,12 @@ commands = [
"add_vertex",
"alias",
"bifurcations",
"binomial_reduction_ODE",
"canonical",
"change_parameter_to_variable",
"check_conservations",
"check_ctl",
"check_ltl",
"check_model",
"check_multistability",
"check_oscillations",
"cleanup_ctl",
......@@ -40,12 +40,14 @@ commands = [
"clear_variation",
"clear_variations",
"compile_from_expression",
"compile_from_ode",
"compile_from_pivp",
"compile_program",
"compile_program_file",
"compile_transfer_function",
"compile_wgpac",
"continue",
"correct_model",
"delete_alias",
"delete_attribute",
"delete_column",
......@@ -147,6 +149,7 @@ commands = [
"list_stable_states",
"list_tables",
"list_tscc_candidates",
"list_units",
"load",
"load_biocham",
"load_ginml",
......@@ -183,12 +186,13 @@ commands = [
"polynomial_ODE",
"present",
"prolog",
"quadratic_reduction_ODE",
"quit",
"rate_independence_reduction",
"rate_independence_reduction_inputs_sinks",
"reaction_graph",
"reaction_model",
"read_xpp",
"reduce_model",
"remove_fraction",
"rename_column",
"rename_table",
"reset_options",
......@@ -213,8 +217,8 @@ commands = [
"set_model_name",
"set_ode_system_name",
"set_p_m_rate",
"set_units",
"test_rate_independence",
"test_rate_independence_inputs_sinks",
"test_rate_independence_invariants",
"transition",
"tropicalize",
......@@ -223,4 +227,5 @@ commands = [
"variation",
"which_p_m_mode",
"with_timer",
"write_xpp",
]
"""Example magic"""
__version__ = '4.4.14'
__version__ = '4.4.15'
......@@ -69,6 +69,7 @@ def get_data_and_meta(filename):
to_show = metadata[1].split(' ')[1:]
against = metadata[2].split(' ')[1]
axes = metadata[3].split(' ')[1:5]
axes_names = (' '.join(metadata[4].split(' ')[1:]), ' '.join(metadata[5].split(' ')[1:]))
with open(filename, newline='') as csvfile:
lines = list(csv.reader(csvfile))
......@@ -78,7 +79,8 @@ def get_data_and_meta(filename):
'logscale': logscale,
'to_show': to_show,
'against': against,
'axes': axes}
'axes': axes,
'axes_names': axes_names}
def create_bokeh_plot(data, gui=False):
......@@ -100,7 +102,8 @@ def create_bokeh_plot(data, gui=False):
bokeh_loaded = True
fig = figure(
x_axis_label=against,
x_axis_label=data['axes_names'][0],
y_axis_label=data['axes_names'][1],
x_axis_type='log' if 'x' in logscale else 'linear',
y_axis_type='log' if 'y' in logscale else 'linear',
tools='pan,wheel_zoom,box_zoom,reset,save,undo',
......@@ -214,7 +217,7 @@ def handle_bokeh_plot(fig, gui_fig, against, cds=None, gui_cds=None, old_handle=
# set the data of the old plot to what we just read
old_data.data = dict(cds.data)
# and display it
push_notebook(old_handle)
push_notebook(handle=old_handle)
return old_handle, old_data
......
......@@ -35,7 +35,7 @@ The following files can also be used to export some Biocham objects:
:- doc('\\section{Biocham call options}').
do_arguments :-
current_prolog_flag(argv, [_Exec | Args]),
current_prolog_flag(os_argv, [_Exec | Args]),
do_arguments(Args).
......
:- use_module(library(plunit)).
:- use_module(library(lists)).
:- use_module(reaction_rules).
:- begin_tests(conservation_laws, [setup((clear_model, reset_options))]).
......
......@@ -32,12 +32,34 @@ derivate_raw(A - B, Variable, Aprime - Bprime) :-
derivate_raw(A, Variable, Aprime),
derivate_raw(B, Variable, Bprime).
derivate_raw(A * B, Variable, Aprime * B) :-
derivate(B, Variable, 0),
!,
derivate_raw(A, Variable, Aprime).
derivate_raw(A * B, Variable, A * Bprime) :-
derivate(A, Variable, 0),
!,
derivate_raw(B, Variable, Bprime).
derivate_raw(A * B, Variable, A * Bprime + Aprime * B) :-
!,
derivate_raw(A, Variable, Aprime),
derivate_raw(B, Variable, Bprime).
% simplify a'b - ab' especially for MM case
derivate_raw(A / B, Variable, D / (B ^ 2)) :-
derivate(A, Variable, 0),
!,
derivate_raw(B, Variable, Bprime),
additive_normal_form((- A * Bprime), C),
simplify(C, D).
derivate_raw(A / B, Variable, Aprime/B) :-
derivate(B, Variable, 0),
!,
derivate_raw(A, Variable, Aprime).
derivate_raw(A / B, Variable, D / (B ^ 2)) :-
!,
derivate_raw(A, Variable, Aprime),
......@@ -47,7 +69,14 @@ derivate_raw(A / B, Variable, D / (B ^ 2)) :-
derivate_raw(A ^ B, Variable, Result) :-
!,
derivate_raw(exp(B * log(A)), Variable, Result).
(
derivate(B, Variable, 0)
->
derivate(A, Variable, Aprime),
Result = Aprime*B*A^(B-1)
;
derivate_raw(exp(B * log(A)), Variable, Result)
).
derivate_raw(sqrt(A), Variable, Result) :-
!,
......
......@@ -12,10 +12,13 @@ test('dx/dt(x^2) = 2x', [true(E == 2 * x)]) :-
derivate(x ^ 2, x, E).
test('dx/dt(cos(sqrt(x))) = - 0.5 / sqrt(x) * sin(sqrt(x))',
[true(E == - (1 / sqrt(x) / 2 * sin(sqrt(x))))]) :-
[true(E == - ( x^(-0.5) / 2 * sin(sqrt(x))))]) :-
derivate(cos(sqrt(x)), x, E).
test('derivate quotient', [true(E == -1*x / y^2)]) :-
derivate(x/y, y, E).
test('derivate real test 1', [true(D == a*c^2)]) :-
derivate(a*b*c^2, b, D).
:- end_tests(formal_derivation).
......@@ -34,6 +34,7 @@ Rq: The distinction between pivp_string and pivp_list is not always obvious.
compile_from_expression/3,
compile_from_pivp/2,
compile_from_pivp/3,
compile_from_ode/2,
%Grammar
polynomial/1,
monomial/1,
......@@ -45,7 +46,7 @@ Rq: The distinction between pivp_string and pivp_list is not always obvious.
:- use_module(library(clpfd)).
:- use_module(doc).
:- use_module(binomial_reduction).
:- use_module(quadratic_reduction).
:- use_module(biocham).
:- use_module(lazy_negation_gpac).
:- use_module(objects).
......@@ -63,12 +64,12 @@ Rq: The distinction between pivp_string and pivp_list is not always obvious.
%%% Main Tools of the module %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
:- doc('The option for binomial reduction restricts the synthesis to reactions with at
:- doc('The option for quadratic reduction restricts the synthesis to reactions with at
most two reactants (the default is not, since this process may be costly).
Two methods are available to perform this a posteriori reduction: natively
or using an external SAT solver.').
:- initial(option(binomial_reduction: no)).
:- initial(option(quadratic_reduction: no)).
:- doc('Another option is the lazy introduction of molecular species for negative real values (the default is yes).').
......@@ -96,10 +97,10 @@ compile_from_expression(Expr, Output) :-
The expression is restricted to standard functions and simple operations using a functional notation where \\texttt{id} represents the time operand.
'),
option(
binomial_reduction,
quadratic_reduction,
reduction_methods,
_Reduction,
'Determine if the binomial reduction for synthesizing reactions with at most two reactants has to be performed'
'Determine if the quadratic reduction for synthesizing reactions with at most two reactants has to be performed'
),
option(
lazy_negatives,
......@@ -111,7 +112,7 @@ compile_from_expression(Expr, Output) :-
negation_first,
yesno,
_Negation_first,
'Determine if the negation of variables is perform before or after the binomialisation'
'Determine if the negation of variables is perform before or after the quadratization'
),
expression_to_PIVP(Expr, PIVP),
PIVP = [N, _PODE, _IC],
......@@ -143,10 +144,10 @@ compile_from_expression(Expr, Input, Output) :-
The Input species is initialized with the value of a special parameter named input. This species may be degraded by the computation.
'),
option(
binomial_reduction,
quadratic_reduction,
reduction_methods,
_Reduction,
'Determine if the binomial reduction for synthesizing reactions with at most two reactants has to be performed'
'Determine if the quadratic reduction for synthesizing reactions with at most two reactants has to be performed'
),
option(
lazy_negatives,
......@@ -307,10 +308,10 @@ compile_from_pivp(PIVP, Output) :-
creates a CRN that immplements a function of time, specified by the variable "Output" of the solution of the PIVP.
'),
option(
binomial_reduction,
quadratic_reduction,
reduction_methods,
_Reduction,
'Determines if the binomial reduction has to be performed'
'Determines if the quadratic reduction has to be performed'
),
sort_output(PIVP, Output, PIVP_sorted),
compile_from_pivp(PIVP_sorted, time, Output).
......@@ -332,7 +333,7 @@ compile_from_pivp(PIVP, Output) :-
\\begin{example} Compilation of the Hill function of order 2 as a function of time, $h(t)=t^2/(1+t^2)$ \n
').
%:- biocham(option(lazy_negatives:yes)).
:- biocham(option(binomial_reduction:native)).
:- biocham(option(quadratic_reduction:native)).
:- biocham(compile_from_pivp((0.0,d(h)/dt= 2*n^2*t;1.0,d(n)/dt= -2*n^2*t;0.0,d(t)/dt=1),h)).
:- biocham(list_model).
:- biocham(numerical_simulation(time:10)). % method:msbdf
......@@ -365,30 +366,64 @@ compile_from_pivp(PIVP, Input, Output) :-
The "Input" variable must not appear in the PIVP. It is created and initialized with a parameter named "input".
'),
option(
binomial_reduction,
quadratic_reduction,
reduction_methods,
_Reduction,
'Determines if the binomial reduction has to be performed'
'Determines if the quadratic reduction has to be performed'
),
sort_output(PIVP, Output, PIVP_sorted),
format_pivp(PIVP_sorted, P, Name_list),
main_compiler(P, Name_list, Input).
%! compile_from_ode(+Input, +Output)
%
% Same as compile_from_pivp but load ODE from the current ode system
compile_from_ode(Input, Output) :-
biocham_command,
type(Input, name),
type(Output, name),
doc('Compile the current ODE system in a CRN, Input is usually "time" but could be the name of a new species, Output have to be the name of an existing variable.'),
option(
quadratic_reduction,
reduction_methods,
_Reduction,
'Determines if the quadratic reduction has to be performed'
),
option(
lazy_negatives,
yesno,
_Lazyness,
'Switch between systematic and lazy introduction of molecular species for negative values'
),
(
% test the polynomiality of the current ode_system
with_current_ode_system(forall(ode(_Var, Expr),is_polynomial(Expr))),
read_ode_system(PIVP),
sort_output(PIVP, Output, PIVP_sorted),
format_pivp(PIVP_sorted, P, Name_list),
main_compiler(P, Name_list, Input)
;
format("The current ODE system is not polynomial.~n", [])
).
:- doc('
\\begin{example} Compilation of the Hill function of order 2 as a function of an input $h(x)=x^2/(1+x^2)$.
This time \\texttt{sat_species} is used (minimizing the number of variables as is the case for \\texttt{native}) and then
\\texttt{sat_reactions} that minimizes the number of monomes.
').
%:- biocham(option(lazy_negatives:yes)).
:- biocham(option(binomial_reduction:sat_species)).
:- biocham(option(quadratic_reduction:sat_species)).
:- biocham(compile_from_pivp((0.0,d(h)/dt= 2*n^2*t;1.0,d(n)/dt= -2*n^2*t;0.0,d(t)/dt=1),x,h)).
:- biocham(parameter(input=2)).
:- biocham(list_model).
:- biocham(numerical_simulation(time:10)). % method:msbdf
:- biocham(plot(show:{h})).
:- biocham(plot(show:{h}, logscale:x)).
:- biocham(compile_from_pivp((0.0,d(h)/dt= 2*n^2*t;1.0,d(n)/dt= -2*n^2*t;0.0,d(t)/dt=1),x,h, binomial_reduction: sat_reactions)).
:- biocham(compile_from_pivp((0.0,d(h)/dt= 2*n^2*t;1.0,d(n)/dt= -2*n^2*t;0.0,d(t)/dt=1),x,h, quadratic_reduction: sat_reactions)).
:- biocham(list_model).
:- doc('
\\end{example}
......@@ -412,7 +447,7 @@ compile_from_pivp(PIVP, Input, Output) :-
%! main_compiler(+PIVP_list, +Name_list, +Input)
%
% Compile a PIVP_list, this predicate dispatch the various options of compilation
% it first check if the PIVP should be reduce to a binomial form
% it first check if the PIVP should be reduce to a quadratic form
% then implement a lazy negation if asked
% when Input is not time it then call g_to_c_PIVP/3.
% and finally make a call to compile_to_biocham_model to make the final implementation
......@@ -430,13 +465,13 @@ main_compiler(PIVP_raw, Name_list_raw, Input):-
g_to_c_PIVP(PIVP_raw, PIVP_input, 1.0),
append(Name_list_raw, [Input], Name_list_input)
),
( % determine the order for binomialisation/negation
( % determine the order for quadratization/negation
NegFirst = yes
->
negation_step(PIVP_input, Name_list_input, PIVP_tempo, Name_list_tempo),
binomialization_step(PIVP_tempo, Name_list_tempo, PIVP_final, Name_list_final)
quadratization_step(PIVP_tempo, Name_list_tempo, PIVP_final, Name_list_final)
;
binomialization_step(PIVP_input, Name_list_input, PIVP_tempo, Name_list_tempo),
quadratization_step(PIVP_input, Name_list_input, PIVP_tempo, Name_list_tempo),
negation_step(PIVP_tempo, Name_list_tempo, PIVP_final, Name_list_final)
),
!, % avoid strangebacktrack effect while loading file
......@@ -464,8 +499,8 @@ negation_step(PIVP_input, Names_input, PIVP_output, Names_output) :-
true
).
binomialization_step(PIVP_input, Names_input, PIVP_output, Names_output) :-
get_option(binomial_reduction, Reduction),
quadratization_step(PIVP_input, Names_input, PIVP_output, Names_output) :-
get_option(quadratic_reduction, Reduction),
(
Reduction \= no
->
......@@ -607,6 +642,36 @@ separate_monomial(X^N, L, [], [], [X^N]) :-
separate_monomial(X, _L, [X], [], []) :- !.
%! read_ode_system(-PIVP)
%
% read the current ode_system and return it as a formated PIVP_string
read_ode_system(PIVP) :-
with_current_ode_system((
get_current_ode_system(Id),
findall(
Stuff,
(
item([parent: Id, kind: ode, item: Item_Der]),
Item_Der = d( Var )/dt = _Deriv,
item([parent: Id, kind: initial_concentration, item: Item_Init]),
Item_Init = init(Var = Num),
Stuff = (Num, Item_Der)
),
PIVP_unf
)
)),
derivative_list_to_pivp(PIVP_unf, PIVP).
% derivative_list_to_pivp(+List, -PIVP)
derivative_list_to_pivp([Head|[]], Head) :- !.
derivative_list_to_pivp([Head|Tail], Head;MTail) :-
!,
derivative_list_to_pivp(Tail, MTail).
%! make_exponent(+Var, +List_var, -Expo)
%
% from the variable present in a monomial, construct the exponent
......@@ -673,9 +738,9 @@ extract_names((_IC, d(Name)/dt = _Deriv; Remainder), [Name|Tail]) :-
% A monomial is a unique object of the form: [K,[Exp1,Exp2,Exp3]]
% corresponding to the term K v1^Exp1 V2^Exp2 etc.
:- dynamic(input_name/1,
output_name/1,
name_spec/0).
:- dynamic(input_name/1).
:- dynamic(output_name/1).
:- dynamic(name_spec/0).
%! compare_exponants(+ExponentSet1,+ExponentSet2,-Comparator)
%
......
......@@ -2,7 +2,8 @@
kinetics,
[
kinetics/4,
add_coefficient/2
add_coefficient/2,
present_in_kinetics/2
]
).
......@@ -95,6 +96,19 @@ make_sum([RS * RO | Tail], S, O, Expression, Sum) :-
add_coefficient(C, 1 * C).
%! present_in_kinetics(+Molecule, +Kinetics)
%
% Test if the Molecule (or whatever actually) is present in the kinetics
present_in_kinetics(Molecule, Molecule) :- !.
present_in_kinetics(Molecule, Kinetics) :-
Kinetics =.. [_Functor|Decomposed],
present_in_kinetics_sr(Molecule, Decomposed).
present_in_kinetics_sr(Molecule, [Head|Tail]) :-
present_in_kinetics(Molecule, Head),!;
present_in_kinetics_sr(Molecule, Tail).
:-doc('Useful abbreviations for mass action law kinetics (with inhibitors), Michaelis-Menten kinetics, Hill kinetics (with inhibitors).').
......
/**
A rewriting of the lazy negation module to be used with the gpac representation of a
PIVP, the purpose was to be able to negate the PIVP after the binomial reduction.
PIVP, the purpose was to be able to negate the PIVP after the quadratic reduction.
For the record, gpac PIVP are represented as pivp_list that is:
pivp_list - a list description of the PIVP used for internal computation
......