Commit e5618dfd authored by David Rosenblueth's avatar David Rosenblueth

Merge NuSMV for influence model with last master

parents 97906db1 48533cdb
ADDITIONAL_MODULES=modules/sbml/sbml_utils.pl
ADDITIONAL_MODULES=modules/sbml/sbml_utils.pl modules/partialfrac/partialfraction.pl
MODULES=$(shell sed -n -E 's/^[+-] (.*\.pl)$$/\1/p' toc.org) \
$(ADDITIONAL_MODULES)
# load_test_files/1 should make this useless, but I cannot find how to use it
......@@ -12,13 +12,13 @@ $(foreach var, CC PLBASE PLCFLAGS PLLDFLAGS PLLIB, \
grep ^$(var)= | \
sed -E 's/="/=/;s/";$$//')))
INCLUDEDIRS=modules/graphviz modules/sbml $(PLBASE)/include
INCLUDEDIRS=modules/graphviz modules/sbml modules/partialfrac $(PLBASE)/include
CFLAGS=$(addprefix -I, $(INCLUDEDIRS)) $(PLCFLAGS)
LDFLAGS=$(PLLDFLAGS) $(addprefix -L, $(dir $(wildcard $(PLBASE)/lib/*/)))
LDLIBS=$(PLLIB) `pkg-config --libs libgvc libsbml`
LDLIBS=$(PLLIB) `pkg-config --libs libgvc libsbml` -lgsl -lgslcblas -lm
SWIPL=$(PWD)/swipl-biocham
......@@ -38,7 +38,8 @@ biocham_debug: platform/current swipl-biocham $(MODULES) $(TEST_MODULES) \
swipl-biocham: swipl-biocham.o \
modules/graphviz/graphviz_swiprolog.o \
modules/sbml/sbml_swiprolog.o
modules/sbml/sbml_swiprolog.o \
modules/partialfrac/roots.o
swipl-biocham.o: swipl-biocham.c
......@@ -48,6 +49,9 @@ modules/graphviz/graphviz_swiprolog.o:
modules/sbml/sbml_swiprolog.o:
make -C modules/sbml
modules/partialfrac/roots.o:
make -C modules/partialfrac
platform/current:
- rm platform/current
ln -s `uname` platform/current
......
Je voulais te préciser que la documentation est générée automatiquement à partir du code
et que c’est bien de commencer par les prédicats qui seront documentés
avant même de les programmer complètement.
Par exemple regarde dans le fichier odefunction.pl:
- on définit un module pour la commande add_function qui est exportée du module.
- le but devdoc crée une nouvelle section dans la documentation
(l’ordre de chargement des modules est déterminé dans le fichier
détermine l’ordre des sections dans la doc
- on définit le prédicat add_function en disant
add_function(FunctionList) :-
- qu’il a un nombre variable d’arguments traités en liste
biocham_command(*),
type(FunctionList, '*'(term = term)),
- que ce prédicat se retrouvera documenté et donn& avec un exemple (exécuté et inséré dans la doc par make)
doc('
adds reactions to compute the result of a function of the current variables in the concentration of a new variable at steady state.
\\begin{example}
'),
biocham_silent(clear_model),
biocham(present(x,1)),
biocham(present(y,3)),
biocham(add_function(z=x+y)),
biocham(list_reactions),
biocham(list_ode),
doc('
\\end{example}
‘),
- puis vient l’implémentation en Prolog
new_ode_system(OdeSystem),
export_ode(FunctionList, OdeSystem),
import_reactions_from_ode_system(OdeSystem),
delete_item(OdeSystem).
Par ailleurs tous les fichiers plt sont exécutés comme des programmes de test.
C’est bien aussi de les écrire pour tester l’implémentation
et de les cometre pour tester les upgrade futurs.
Par exemple odefunction.plt
......@@ -11,7 +11,7 @@
version('4.0').
copyright(
'Copyright (C) 2003-2015 Inria, EPI Lifeware, Paris-Rocquencourt, France'
'Copyright (C) 2003-2016 Inria, EPI Lifeware, Saclay-Île de France, France'
).
license('GNU GPL 2').
......
......@@ -25,15 +25,40 @@ simplify(In, Out) :-
simplify_aux(In, Out) :-
additive_block(In, Blocks),
!,
simplify_blocks(additive_block, additive_index, rebuild_additive_coef, Blocks, CoefSubBlocks),
simplify_blocks(additive_block, additive_index, Blocks, ReducedSubBlocks),
maplist(rebuild_additive_coef, ReducedSubBlocks, CoefSubBlocks),
rebuild_additive_blocks(CoefSubBlocks, Out).
simplify_aux(In, Out) :-
multiplicative_block(In, Blocks),
!,
simplify_blocks(multiplicative_block, multiplicative_index, rebuild_multiplicative_coef, Blocks, CoefSubBlocks),
simplify_blocks(multiplicative_block, multiplicative_index, Blocks, ReducedSubBlocks),
map_blocks(rebuild_multiplicative_coef, ReducedSubBlocks, CoefSubBlocks),
compute_product(CoefSubBlocks, CoefSubBlocksComputed),
rebuild_multiplicative_blocks(CoefSubBlocksComputed, Out).
rebuild_multiplicative_blocks(CoefSubBlocksComputed, OutCoef),
(
extract_coefficient(OutCoef, Coef, SubOut),
Coef < 1
->
(
Coef < 0
->
CoefAbs is - Coef,
Out = - OutAbs
;
CoefAbs = Coef,
Out = OutAbs
),
(
CoefAbs = 1
->
OutAbs = SubOut
;
insert_coef(SubOut, CoefAbs, OutAbs)
)
;
Out = OutCoef
).
simplify_aux(log(exp(Expr)), Out) :-
!,
......@@ -75,15 +100,17 @@ simplify_aux(In, Out) :-
).
simplify_blocks(Block, Index, RebuildCoef, Blocks, CoefSubBlocks) :-
simplify_blocks(Block, Index, Blocks, ReducedSubBlocks) :-
gather_loop(Block, Blocks, SubBlocks),
maplist(Index, SubBlocks, IndexedSubBlocks),
sort(4, @=<, IndexedSubBlocks, SortedSubBlocks),
check_cleaned(arithmetic_rules:canonical/3),
gather_indexed(SortedSubBlocks),
reduce_blocks(IndexedSubBlocks, ReducedSubBlocks),
clean(arithmetic_rules:canonical/3),
map_blocks(RebuildCoef, ReducedSubBlocks, CoefSubBlocks).
with_clean(
[arithmetic_rules:canonical/3],
(
arithmetic_rules:gather_indexed(SortedSubBlocks),
arithmetic_rules:reduce_blocks(IndexedSubBlocks, ReducedSubBlocks)
)
).
gather_loop(Block, Blocks, SubBlocks) :-
......@@ -100,30 +127,50 @@ gather_loop(Block, Blocks, SubBlocks) :-
compute_product([], []).
compute_product([+ N | T], Out) :-
number(N),
compute_product([B | T], Out) :-
block_number(B, N),
!,
compute_product_with_others(T, PT, Others),
P is N * PT,
P is PT * N,
(
P = 1
->
Out = Others
;
Out = [+ P | Others]
normalize_number(P, PNorm),
Out = [+ PNorm | Others]
).
compute_product([H | TIn], [H | TOut]) :-
compute_product(TIn, TOut).
block_number(B, N) :-
sign(B, Sign, C),
(
number(C),
V = C
;
C = M ^ E,
number(M),
V is M ^ E
),
(
Sign = 1
->
N = V
;
N is 1 / V
).
compute_product_with_others([], 1, []).
compute_product_with_others([+ N | T], P, Others) :-
number(N),
compute_product_with_others([B | T], P, Others) :-
block_number(B, N),
!,
compute_product_with_others(T, PT, Others),
P is N * PT.
P is PT * N.
compute_product_with_others([H | TIn], P, [H | TOut]) :-
compute_product_with_others(TIn, P, TOut).
......@@ -204,14 +251,39 @@ additive_index(H, index(Expr, Sign, Coef, Others, Canonical)) :-
canonical_expression(Others, Canonical).
extract_coefficient(C, C, 1) :-
number(C),
!.
extract_coefficient(- CA, COpp, A) :-
extract_coefficient(CA, C, A),
!,
COpp is - C.
extract_coefficient(+ CA, C, A) :-
extract_coefficient(CA, C, A),
!.
extract_coefficient(A * B, A, B) :-
number(A).
number(A),
!.
extract_coefficient(A / B, A, 1 / B) :-
number(A),
!.
extract_coefficient(A * B, B, A) :-
number(B).
number(B),
!.
extract_coefficient(A / B, BInv, A) :-
number(B),
!,
BInv is 1 / B.
extract_coefficient(CA * B, C, A * B) :-
extract_coefficient(CA, C, A).
extract_coefficient(CA, C, A),
!.
extract_coefficient(A * CB, C, A * B) :-
extract_coefficient(CB, C, B).
......@@ -258,23 +330,49 @@ canonical_expression(In, Out) :-
term_morphism(arithmetic_rules:canonical_expression, In, Out).
rebuild_additive_coef(Block, Value) :-
rebuild_additive_coef(SignedBlock, Value) :-
sign(SignedBlock, Sign, Block),
(
Block = (Coef : Expr)
->
SignedCoef is Sign * Coef,
(
Coef = 1
SignedCoef = 1
->
Value = Expr
Value = + Expr
;
Expr = 1
->
Value = Coef
Value = + SignedCoef
;
insert_coef(Expr, Coef, Value)
(
extract_coefficient(Expr, OtherCoef, SubExpr)
->
FullCoef is SignedCoef * OtherCoef
;
FullCoef = SignedCoef,
SubExpr = Expr
),
(
FullCoef < 0
->
NewSign = -1,
NewCoef is - FullCoef
;
NewSign = 1,
NewCoef = FullCoef
),
(
NewCoef = 1
->
UnsignedValue = SubExpr
;
insert_coef(SubExpr, NewCoef, UnsignedValue)
),
sign(Value, NewSign, UnsignedValue)
)
;
Value = Block
Value = + Block
).
......@@ -282,7 +380,19 @@ insert_coef(A * B, Coef, Result * B) :-
!,
insert_coef(A, Coef, Result).
insert_coef(A, Coef, Coef * A).
insert_coef(A, Coef, Result) :-
(
Coef > 0,
Coef < 1,
CoefInv is 1 / Coef,
0.0 is float_fractional_part(CoefInv)
->
normalize_number(CoefInv, CoefInvNorm),
Result = A / CoefInvNorm
;
normalize_number(Coef, CoefNorm),
Result = CoefNorm * A
).
rebuild_multiplicative_coef(Block, Value) :-
......@@ -420,6 +530,9 @@ additive_block(A + B, [+A, +B]).
additive_block(A - B, [+A, -B]).
multiplicative_block(+ A, [+A]).
multiplicative_block(- A, [+(-1), +A]).
multiplicative_block(A * B, [+A, +B]).
......@@ -588,3 +701,18 @@ always_positive(A / B) :-
always_positive(A / B) :-
always_negative(A),
always_negative(B).
normalize_number(N, Norm) :-
(
F is float_fractional_part(N),
(
F = 0
;
F = 0.0
)
->
Norm is truncate(N)
;
Norm = N
).
......@@ -11,16 +11,18 @@
:- doc('
The Biochemical Abstract Machine (Biocham) is a software environment for
modeling and analyzing biochemical systems.
Biocham is mainly composed of~:
Biocham is mainly composed of:
\\begin{itemize}
\\item a rule-based language for modeling biochemical systems (compatible with
SBML and SBGN),
\\item different simulators (Boolean, differential, stochastic),
\\item a temporal logic based language to formalize the temporal properties of
a biological system and validate models with respect to such specifications,
\\item static analysers for inferring various dynamical properties from the structure of the model;
\\item simulators for the different semantics: continuous (differential equations), stochastic, asynchronous Boolean;
\\item a temporal logic based language to formalize the temporal behaviours of
biological systems, validate models with respect to such specifications by model-checking methods,
infer parameter values in high dimension with temporal logic constraints,
measure parameter sensitivity indices and robustness of temporal properties;
\\item unique features for developing/correcting/completing/reducing/coupling
models, including the inference of kinetic parameters in high dimension from
temporal logic constraints.
models.
\\end{itemize}
Biocham is a free software protected by the GNU General Public License GPL
version 2. This is an Open Source license that allows free usage of this
......
This diff is collapsed.
:- module(
events,
[
% Public API
add_event/2,
list_events/0
list_events/0,
list_model_events/0
]
).
:- devdoc('\\section{Commands}').
add_event(Condition, ParameterValues) :-
biocham_command(*),
type(Condition, condition),
type(ParameterValues, '*'(parameter = simple_kinetics)),
type(ParameterValues, '*'(parameter = arithmetic_expression)),
doc('
sets up an event that will be fired each time the condition given as first
argument goes from false to true.
This command is effective in numerical simulations only.
Upon firing, the parameters receive new values
computed from the expression.
The initial values of the parameters are restored after the simulation.'),
\+ (
member(ParameterValue, ParameterValues),
\+ (
add_item(event, event(Condition, ParameterValue))
)
).
The initial values of the parameters are restored after the simulation.
\\begin{example}
'),
biocham_silent(clear_model),
biocham('MA'(k) for a => b),
biocham(set_parameter(k = 1)),
biocham(add_event(b > 0.5, k = 0)),
biocham(present(a)),
biocham(numerical_simulation(2, maximum_step_size: 1e-3)),
biocham(plot),
doc('
\\end{example}
'),
add_item([kind: event, item: event(Condition, ParameterValues)]).
list_events :-
biocham_command,
doc('lists all the declared events.'),
list_items([kind: event]).
:- devdoc('\\section{Private predicates}').
list_model_events :-
devdoc('
lists all the events in a loadable syntax
(auxiliary predicate of list_model).
'),
\+ (
item(
[no_inheritance, kind: event, item: event(Condition, ParameterValues)]
),
\+ (
format('add_event(~w, ', [Condition]),
write_successes(
member(Parameter = Value, ParameterValues),
write(', '),
format('~w = ~w', [Parameter, Value])
),
write(').\n')
)
).
......@@ -8,6 +8,11 @@
]
).
:- doc('This reference manual (and its extended version for developpers) is automaticaly generated from the source code of Biocham.
The syntax of Biocham is described with formal grammar rules which define new syntactic tokens from primitive tokens such as atom (i.e. string), number, term (e.g. atom(..., ...)).
For instance, the syntax of an input or output file is just the syntax of an atom in both cases, but they are distinguished in this manual for documentation purposes:').
:- grammar(input_file).
......
......@@ -12,7 +12,7 @@ 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 == - (0.5 / sqrt(x)) * sin(sqrt(x)))]) :-
[true(E == - (1 / sqrt(x) / 2 * sin(sqrt(x))))]) :-
derivate(cos(sqrt(x)), x, E).
:- end_tests(formal_derivation).
......@@ -25,6 +25,7 @@ function(FunctionList) :-
member(Function = Value, FunctionList),
\+ (
Function =.. [Functor | _Arguments],
check_identifier_kind(Functor, function),
catch(
(
find_item([kind: function, key: Functor, id: Id]),
......@@ -96,19 +97,10 @@ list_model_functions :-
item([no_inheritance, kind: function])
->
write('function(\n'),
assertz(first),
\+ (
write_successes(
item([no_inheritance, kind: function, item: function(Head = Body)]),
\+ (
(
retract(first)
->
true
;
write(',\n')
),
format(' ~w = ~w', [Head, Body])
)
write(',\n'),
format(' ~w = ~w', [Head, Body])
),
write('\n).\n')
;
......
:- module(
graph_editor,
[
% Grammars
attribute/1,
edge/1,
edgeref/1,
% Commands
new_graph/0,
delete_graph/1,
set_graph_name/1,
......@@ -8,35 +13,77 @@
select_graph/1,
add_vertex/1,
delete_vertex/1,
edge/1,
add_edge/1,
edgeref/1,
delete_edge/1,
list_edges/0,
list_isolated_vertices/0,
list_graph_objects/0,
graph_object/1,
attribute/1,
set_attribute/2,
delete_attribute/2,
list_attributes/1,
place/1,
transition/1,
% Public API
new_graph/1,
set_graph_name/2,
get_current_graph/1,
set_current_graph/1,
get_graph_name/2,
get_attribute/2
get_attribute/2,
get_attribute/3,
set_attribute/3,
place/2,
place/3,
transition/2,
transition/3,
kind/3,
kind/4,
add_vertex/3,
add_edge/3,
add_edge/4
]
).
:- devdoc('\\section{Grammars}').
:- grammar(attribute).
attribute(Key = Value) :-
name(Key),
term(Value).
attribute(Name) :-
name(Name).
:- grammar(edge).
edge(From -> To) :-
name(From),
name(To).
:- grammar(edgeref).
edgeref(Edge) :-
edge(Edge).
:- devdoc('\\section{Commands}').
new_graph :-
biocham_command,
doc('Creates a new graph.'),
add_item([kind: graph, key: new_graph, id: Id]),
new_graph(Id),
set_current_graph(Id).
......@@ -52,7 +99,7 @@ set_graph_name(Name) :-
type(Name, name),
doc('Sets the name of the current graph.'),
get_current_graph(Id),
replace_item(Id, graph, Name, Name).
set_graph_name(Id, Name).
list_graphs :-
......@@ -73,10 +120,11 @@ add_vertex(NameList) :-
biocham_command(*),
type(NameList, '*'(name)),
doc('Adds new vertices to the current graph.'),
get_current_graph(GraphId),
\+ (
member(Name, NameList),
\+ (
add_vertex(Name, _VertexId)
add_vertex(GraphId, Name, _VertexId)
)
).
......@@ -94,14 +142,6 @@ delete_vertex(NameList) :-
).
:- grammar(edge).
edge(From -> To) :-
name(From),
name(To).
add_edge(EdgeList) :-
biocham_command(*),
type(EdgeList, '*'(edge)),
......@@ -109,21 +149,15 @@ add_edge(EdgeList) :-
Adds the given set of edges to the current graph.
The vertices are added if needed.
'),
get_current_graph(GraphId),
\+ (
member(Edge, EdgeList),
\+ (
add_edge(Edge, _EdgeId)
add_edge(GraphId, Edge, _EdgeId)
)
).
:- grammar(edgeref).
edgeref(Edge) :-
edge(Edge).
delete_edge(EdgeRefList) :-
biocham_command(*),
type(EdgeRefList, '*'(edgeref)),
......@@ -175,15 +209,31 @@ graph_object(Name) :-
name(Name).
:- grammar(attribute).
attribute(Key: Value) :-
name(Key),
term(Value).
attribute(Name) :-
name(Name).
set_attribute(Id, Attribute) :-
integer(Id),
!,
(
Attribute = (Key = _Value)
->
true
;
Key = Attribute
),
(
item(
[parent: Id, kind: attribute, key: Key, item: Item, id: AttributeId]
)
->
(
Item = Attribute
->
true
;
replace_item(AttributeId, attribute, Key, Attribute)
)
;
add_item([parent: Id, kind: attribute, key: Key, item: Attribute])
).
set_attribute(GraphObjectSet, Attribute) :-
......@@ -194,34 +244,8 @@ set_attribute(GraphObjectSet, Attribute) :-
Adds an attribute to every vertex or edge in the given set.
The vertices and the edges are added if needed.
'),
\+ (
member(GraphObject, GraphObjectSet),
\+ (
add_graph_object(GraphObject, Id),
(