Commit 4beba5d4 authored by Thierry Martinez's avatar Thierry Martinez
parents e36e4831 62febb13
......@@ -10,7 +10,8 @@
check_influence_model/0,
with_influence_model/1,
list_model_influences/0,
influence/6
influence/6,
compute_ode_for_influence_model/0
]
).
......@@ -135,7 +136,7 @@ influence(InfluenceRule, Force, PositiveInputs, NegativeInputs, Sign, Output) :-
'builds or decomposes an influence rule.'
),
once((
Force = 1,
Force = 'MA'(1),
(
var(InfluenceRule)
->
......@@ -157,9 +158,30 @@ influence(InfluenceRule, Force, PositiveInputs, NegativeInputs, Sign, Output) :-
inputs(Inputs, PositiveInputs, NegativeInputs).
compute_ode_for_influence_model :-
\+ (
item([kind: influence, item: Item]),
influence(Item, Force, PositiveInputs, _NegativeInputs, Sign, Output),
\+ (
maplist(add_coefficient, PositiveInputs, PositiveInputsWithCoefficient),
kinetics(PositiveInputsWithCoefficient, Force, ForceExpression),
sign(Sign, ForceExpression, SignedForce),
ode_add_expression_to_molecule(SignedForce, Output)
)
).
:- devdoc('\\section{Private predicates}').
add_coefficient(C, 1 * C).
sign(-, Force, - Force).
sign(+, Force, Force).
influence_model(ReactionModel, InfluenceModel) :-
\+ (
item([parent: ReactionModel, kind: reaction, item: Reaction]),
......
......@@ -48,19 +48,19 @@ test(
'influence builds with positive inputs',
[Influence == (b -< c)]
) :-
influence(Influence, 1, [b], [], -, c).
influence(Influence, 'MA'(1), [b], [], -, c).
test(
'influence builds with negative inputs',
[Influence == (\ a -< a)]
) :-
influence(Influence, 1, [], [a], -, a).
influence(Influence, 'MA'(1), [], [a], -, a).
test(
'influence builds with no inputs',
[Influence == ('_' -> a)]
) :-
influence(Influence, 1, [], [], +, a).
influence(Influence, 'MA'(1), [], [], +, a).
test(
'influence destructs',
......@@ -70,14 +70,21 @@ test(
result(2, [a, b], [c], +, d)
]
) :-
influence((2 for a, b \ c -> d), Force, PositiveInputs, NegativeInputs, Sign, Output).
influence(
(2 for a, b \ c -> d),
Force,
PositiveInputs,
NegativeInputs,
Sign,
Output
).
test(
'influence destructs with positive inputs',
[
result(Force, PositiveInputs, NegativeInputs, Sign, Output)
==
result(1, [b], [], -, c)
result('MA'(1), [b], [], -, c)
]
) :-
influence((b -< c), Force, PositiveInputs, NegativeInputs, Sign, Output).
......@@ -87,9 +94,21 @@ test(
[
result(Force, PositiveInputs, NegativeInputs, Sign, Output)
==
result(1, [], [a], -, a)
result('MA'(1), [], [a], -, a)
]
) :-
influence((\ a -< a), Force, PositiveInputs, NegativeInputs, Sign, Output).
test(
'compute_ode_for_influence_model',
[ODEs == [d(a)/dt = -a, d(b)/dt = a]]
) :-
clear_model,
command(a -> b),
command(a -< a),
ode_system,
all_odes(ODEs).
:- end_tests(influence_editor).
:- module(
ode,
[
% Grammars
oderef/1,
op(1000, fx, init),
% Commands
new_ode_system/0,
delete_ode_system/1,
set_ode_system_name/1,
......@@ -8,7 +12,6 @@
select_ode_system/1,
ode/1,
add_ode/1,
oderef/1,
delete_ode/1,
list_ode/0,
ode_system/0,
......@@ -18,6 +21,7 @@
load_ode_system/1,
add_ode_system/1,
export_ode_system/1,
% Public API
new_ode_system/1,
get_current_ode_system/1,
set_current_ode_system/1,
......@@ -32,10 +36,20 @@
all_odes/1,
ode/2,
ode/3,
op(1000, fx, init)
ode_add_expression_to_molecule/2
]).
:- devdoc('\\section{Grammars}').
:- grammar(oderef).
oderef(X) :-
name(X).
:- devdoc('\\section{Commands}').
......@@ -99,7 +113,9 @@ add_ode(ODEList) :-
type(ODEList, '*'(ode)),
doc('
If there is a current ODE system, adds the given set of ODEs to it.
If there is no current ODE system, imports the reactions inferred from the given set of ODEs.'),
If there is no current ODE system,
imports the reactions inferred from the given set of ODEs.
'),
edit_current_ode_system((
\+ (
member(ODE, ODEList),
......@@ -117,13 +133,6 @@ import_reactions_from_ode_system :-
import_reactions_from_ode_system(Id).
:- grammar(oderef).
oderef(X) :-
name(X).
delete_ode(ODERefList) :-
biocham_command(*),
type(ODERefList, '*'(oderef)),
......@@ -159,7 +168,9 @@ list_ode :-
ode_system :-
biocham_command,
doc('builds the set of ODES corresponding to the reactions of the current model.'),
doc('
builds the set of ODES corresponding to the reactions of the current model.
'),
delete_ode_system('ode_system'),
new_ode_system,
set_ode_system_name('ode_system'),
......@@ -475,14 +486,14 @@ partial_has_pos_val(Term, X) :-
compute_ode :-
\+ (
item([kind: reaction, item: Item]),
reaction(Item, Kinetics, Reactants, Products),
\+ (
kinetics(Reactants, Kinetics, KineticsExpression),
add_molecules(Reactants, -KineticsExpression),
add_molecules(Products, KineticsExpression)
)
(
is_reaction_model
->
compute_ode_for_reaction_model
;
is_influence_model
->
compute_ode_for_influence_model
).
......@@ -496,26 +507,6 @@ simplify_ode :-
).
add_molecules(Molecules, Kinetics) :-
\+ (
member(Molecule, Molecules),
\+ (
add_molecule(Molecule, Kinetics)
)
).
add_molecule(Coefficient * Molecule, Kinetics) :-
(
retract(assoc(Molecule, Expression))
->
true
;
Expression = 0
),
asserta(assoc(Molecule, Expression + Coefficient * Kinetics)).
put_ode_into_system :-
\+ (
assoc(X, Expression),
......@@ -671,3 +662,14 @@ edit_current_ode_system(Goal) :-
)
)
).
ode_add_expression_to_molecule(NewExpression, Molecule) :-
(
retract(assoc(Molecule, Expression))
->
true
;
Expression = 0
),
asserta(assoc(Molecule, Expression + NewExpression)).
......@@ -3,7 +3,7 @@
:- begin_tests(ode).
test('ode_system', [true(ODEs == [d(b)/dt = a, d(a)/dt = -a])]) :-
test('ode_system', [ODEs == [d(b)/dt = a, d(a)/dt = -a]]) :-
clear_model,
command(a => b),
ode_system,
......@@ -11,7 +11,7 @@ test('ode_system', [true(ODEs == [d(b)/dt = a, d(a)/dt = -a])]) :-
test(
'import_ode',
[true(ODEs == [init a = 0, init b = 0, d(a)/dt = -a, d(b)/dt = a])]
[ODEs == [init a = 0, init b = 0, d(a)/dt = -a, d(b)/dt = a]]
) :-
setup_call_cleanup(
open('test.ode', write, TestOde),
......@@ -40,7 +40,10 @@ test(
all_items([kind: reaction], Reactions).
test('export_ode_system', [true(Lines == ['init b = 0', 'init a = 1', 'db/dt = a', 'da/dt = -a', 'done'])]) :-
test(
'export_ode_system',
[Lines == ['init b = 0', 'init a = 1', 'db/dt = a', 'da/dt = -a', 'done']]
) :-
clear_model,
command(a => b),
command(present(a)),
......
......@@ -14,7 +14,8 @@
reaction/4,
enumerate_molecules/1,
solution_to_list/2,
list_to_solution/2
list_to_solution/2,
compute_ode_for_reaction_model/0
]
).
......@@ -389,3 +390,28 @@ enumerate_molecule(Molecule) :-
;
Item = absent
).
compute_ode_for_reaction_model :-
\+ (
item([kind: reaction, item: Item]),
reaction(Item, Kinetics, Reactants, Products),
\+ (
kinetics(Reactants, Kinetics, KineticsExpression),
add_molecules(Reactants, -KineticsExpression),
add_molecules(Products, KineticsExpression)
)
).
add_molecules(Molecules, Kinetics) :-
\+ (
member(Molecule, Molecules),
\+ (
add_molecule(Molecule, Kinetics)
)
).
add_molecule(Coefficient * Molecule, Kinetics) :-
ode_add_expression_to_molecule(Coefficient * Kinetics, Molecule).
:- module(
reaction_rules,
[
reaction_predicate/1,
% Grammars
reaction/1,
basic_reaction/1,
solution/1,
......@@ -13,17 +13,14 @@
op(750, xfx, =>),
op(750, xfx, <=>),
op(700, xfy, =),
op(600, xfx, in)
op(600, xfx, in),
% Public API
reaction_predicate/1
]
).
reaction_predicate(_ for Reaction) :-
reaction_predicate(Reaction).
reaction_predicate(_ => _).
reaction_predicate(_ <=> _).
:- devdoc('\\section{Grammars}').
:- grammar(reaction).
......@@ -183,3 +180,14 @@ arithmetic_expression(Name) :-
arithmetic_expression(FunctionApplication) :-
function_application(arithmetic_expression, FunctionApplication).
:- devdoc('\\section{Public API}').
reaction_predicate(_ for Reaction) :-
reaction_predicate(Reaction).
reaction_predicate(_ => _).
reaction_predicate(_ <=> _).
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