Commit 49afd4b8 authored by MARTINEZ Thierry 's avatar MARTINEZ Thierry

Reaction graphs

parent 7d3ef87c
......@@ -10,14 +10,18 @@
export_graph/1,
add_vertex/1,
delete_vertex/1,
add_attribute/2,
delete_attribute/2,
list_attributes/1,
edge/1,
add_edge/1,
delete_edge/1,
list_edges/0,
get_current_graph/1
graph_object/1,
set_attribute/2,
delete_attribute/2,
list_attributes/1,
place/1,
transition/1,
get_current_graph/1,
get_attribute/2
]
).
......@@ -77,47 +81,21 @@ add_vertex(Name) :-
type(Name, name),
doc('Adds a vertex to the current graph.'),
get_current_graph(GraphId),
add_item([parent: GraphId, kind: vertex, key: Name]).
delete_vertex(Name) :-
biocham_command,
type(Name, name),
doc('Removes a vertex from the current graph.'),
get_current_graph(GraphId),
delete_item([parent: GraphId, kind: vertex, key: Name]).
add_attribute(Name, Attribute) :-
biocham_command,
type(Name, name),
type(Attribute, name),
doc('Adds an attribute to a vertex.'),
find_vertex(Name, Id),
(
find_item([parent: Id, kind: attribute, key: Attribute])
item([parent: GraphId, kind: vertex, key: Name])
->
true
;
add_item([parent: Id, kind: attribute, key: Attribute])
add_item([parent: GraphId, kind: vertex, key: Name])
).
delete_attribute(Name, Attribute) :-
biocham_command,
type(Name, name),
type(Abbribute, name),
doc('Removes an attribute from a vertex.'),
find_vertex(Name, Id),
delete_item([parent: Id, kind: attribute, key: Attribute]).
list_attributes(Name) :-
delete_vertex(Name) :-
biocham_command,
type(Name, name),
doc('List the attributes of a vertex.'),
find_vertex(Name, Id),
list_items([parent: Id, kind: attribute]).
doc('Removes a vertex from the current graph.'),
get_current_graph(GraphId),
delete_item([parent: GraphId, kind: vertex, key: Name]).
:- grammar(edge).
......@@ -136,9 +114,15 @@ add_edge(Edge) :-
find_vertex(From, FromId),
find_vertex(To, ToId),
get_current_graph(GraphId),
add_item([parent: GraphId, kind: edge, key: Edge, id: Id]),
add_dependency(Id, FromId),
add_dependency(Id, ToId).
(
item([parent: GraphId, kind: edge, key: Edge])
->
true
;
add_item([parent: GraphId, kind: edge, key: Edge, id: Id]),
add_dependency(Id, FromId),
add_dependency(Id, ToId)
).
delete_edge(Edge) :-
......@@ -156,6 +140,93 @@ list_edges :-
list_items([parent: GraphId, kind: edge]).
:- grammar(graph_object).
graph_object(Edge) :-
edge(Edge).
graph_object(Name) :-
name(Name).
:- grammar(attribute).
attribute(Key: Value) :-
name(Key),
name(Value).
attribute(Name) :-
name(Name).
set_attribute(GraphObject, Attribute) :-
biocham_command,
type(GraphObject, graph_object),
type(Attribute, attribute),
doc('Adds an attribute to a vertex or an edge.'),
find_graph_object(GraphObject, 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])
).
place(Name) :-
biocham_command,
type(Name, name),
doc('
Sets that the vertex \\argument{Name} is a place.
'),
add_vertex(Name),
set_attribute(Name, kind: place).
transition(Name) :-
biocham_command,
type(Name, name),
doc('
Sets that the vertex \\argument{Name} is a transition.
'),
add_vertex(Name),
set_attribute(Name, kind: transition).
delete_attribute(GraphObject, Attribute) :-
biocham_command,
type(GraphObject, graph_object),
type(Attribute, name),
doc('Removes an attribute from \\argument{GraphObject}.'),
find_graph_object(GraphObject, Id),
delete_item([parent: Id, kind: attribute, key: Attribute]).
list_attributes(GraphObject) :-
biocham_command,
type(GraphObject, graph_object),
doc('List the attributes of \\argument{GraphObject}.'),
find_graph_object(GraphObject, Id),
list_items([parent: Id, kind: attribute]).
:- devdoc('\\section{End of commands}').
......@@ -164,9 +235,24 @@ find_vertex(Name, Id) :-
find_item([parent: GraphId, kind: vertex, key: Name, id: Id]).
find_edge(Edge, Id) :-
get_current_graph(GraphId),
find_item([parent: GraphId, kind: edge, key: Edge, id: Id]).
find_graph_object(GraphObject, Id) :-
(
GraphObject = (_From->_To)
->
find_edge(GraphObject, Id)
;
find_vertex(GraphObject, Id)
).
deselect_graph :-
\+ (
item([kind: Graph, id: Id]),
item([kind: graph, id: Id]),
\+ (
(
delete_annotation(Id, selected)
......@@ -186,10 +272,27 @@ set_current_graph(Id) :-
get_current_graph(Id) :-
(
item([kind: Graph, id: Id]),
item([kind: graph, id: Id]),
get_annotation(Id, selected, selected)
->
true
;
throw(error(no_graph_selected))
).
get_attribute(Id, Attribute) :-
integer(Id),
!,
(
Attribute = Key: _Value
->
true
;
Key = Attribute
),
item([parent: Id, kind: attribute, key: Key, item: Attribute]).
get_attribute(GraphObject, Attribute) :-
find_graph_object(GraphObject, Id),
get_attribute(Id, Attribute).
......@@ -43,39 +43,120 @@ test('add_vertex', [true(Vertices == ['A'])]) :-
clear_model,
new_graph,
add_vertex('A'),
get_current_graph(Id),
all_items([kind: vertex], Vertices).
add_vertex('A'),
get_current_graph(GraphId),
all_items([parent: GraphId, kind: vertex], Vertices).
test('delete_vertex', [true(Vertices == [])]) :-
clear_model,
new_graph,
add_vertex('A'),
delete_vertex('A'),
get_current_graph(Id),
all_items([kind: vertex], Vertices).
get_current_graph(GraphId),
all_items([parent: GraphId, kind: vertex], Vertices).
test('add_edge', [true(Edges == ['A' -> 'B'])]) :-
clear_model,
new_graph,
add_vertex('A'),
add_vertex('B'),
add_vertex('C'),
add_edge('A' -> 'B'),
add_edge('A' -> 'B'),
add_edge('A' -> 'C'),
delete_vertex('C'),
get_current_graph(GraphId),
all_items([parent: GraphId, kind: edge], Edges).
test('delete_edge', [true(Edges == [])]) :-
clear_model,
new_graph,
add_vertex('A'),
add_vertex('B'),
add_edge('A' -> 'B'),
delete_edge('A' -> 'B'),
get_current_graph(GraphId),
all_items([parent: GraphId, kind: edge], Edges).
test('add_attribute', [true(Attributes == ['object'])]) :-
test('list_edges', [true(Atom == '[0] A->B\n')]) :-
clear_model,
new_graph,
add_vertex('A'),
add_attribute('A', object),
add_vertex('B'),
add_edge('A' -> 'B'),
with_output_to(atom(Atom), list_edges).
test('set_attribute vertex', [true(Attributes == ['object', 'item'])]) :-
clear_model,
new_graph,
add_vertex('A'),
set_attribute('A', object),
set_attribute('A', item),
set_attribute('A', object),
get_current_graph(GraphId),
find_item([parent: GraphId, kind: vertex, key: 'A', id: VertexId]),
all_items([parent: VertexId, kind: attribute], Attributes).
test('delete_vertex', [true(Vertices == [])]) :-
test('set_attribute edge', [true(Attributes == [stochiometry: 2])]) :-
clear_model,
new_graph,
add_vertex('A'),
delete_vertex('A'),
get_current_graph(Id),
all_items([kind: vertex], Vertices).
% add_attribute/2,
% delete_attribute/2,
% edge/1,
% add_edge/1,
% delete_edge/1,
% list_edges/0
add_vertex('B'),
add_edge('A' -> 'B'),
set_attribute(('A' -> 'B'), stochiometry: 2),
get_current_graph(GraphId),
find_item([parent: GraphId, kind: edge, key: ('A' -> 'B'), id: EdgeId]),
all_items([parent: EdgeId, kind: attribute], Attributes).
test('place', [true(Attributes == [kind: place])]) :-
clear_model,
new_graph,
transition('A'),
place('A'),
transition('B'),
get_current_graph(GraphId),
find_item([parent: GraphId, kind: vertex, key: 'A', id: VertexId]),
all_items([parent: VertexId, kind: attribute], Attributes).
test('transition', [true(Attributes == [kind: transition])]) :-
clear_model,
new_graph,
place('A'),
transition('A'),
place('B'),
get_current_graph(GraphId),
find_item([parent: GraphId, kind: vertex, key: 'A', id: VertexId]),
all_items([parent: VertexId, kind: attribute], Attributes).
test('delete_attribute', [true(Attributes == [])]) :-
clear_model,
new_graph,
add_vertex('A'),
set_attribute('A', object),
delete_attribute('A', object),
get_current_graph(GraphId),
find_item([parent: GraphId, kind: vertex, key: 'A', id: VertexId]),
all_items([parent: VertexId, kind: attribute], Attributes).
test('list_attributes vertex', [true(Atom == '[0] kind:place\n')]) :-
clear_model,
new_graph,
place('A'),
with_output_to(atom(Atom), list_attributes('A')).
test('list_attributes edge', [true(Atom == '[0] stochiometry:2\n')]) :-
clear_model,
new_graph,
add_vertex('A'),
add_vertex('B'),
add_edge('A' -> 'B'),
set_attribute(('A' -> 'B'), stochiometry: 2),
with_output_to(atom(Atom), list_attributes('A' -> 'B')).
test('get_attribute', [true(Kind == transition)]) :-
clear_model,
new_graph,
transition('A'),
get_attribute('A', kind: Kind).
:- end_tests(graph_editor).
......@@ -433,7 +433,7 @@ item(Options) :-
current_models(Models),
member(Parent0, Models)
;
true
Parent0 = Parent
),
(
var(Key)
......@@ -524,13 +524,25 @@ delete_item(Id) :-
\+ (
item(SubId, Id, _SubKind, _SubItem),
\+ (
delete_item(SubId)
(
delete_item(SubId)
->
true
;
true
)
)
),
\+ (
dependency(SubId, Id),
\+ (
delete_item(SubId)
(
delete_item(SubId)
->
true
;
true
)
)
),
(
......
......@@ -11,12 +11,15 @@ main (int argc, char *argv[])
}
const char *filename = argv[1];
SBMLDocument *document = readSBML(filename);
if (document->getErrorLog()->getNumFailsWithSeverity(LIBSBML_SEV_ERROR)
> 0) {
int severeErrors =
document->getErrorLog()->getNumFailsWithSeverity(LIBSBML_SEV_ERROR);
if (severeErrors > 0) {
document->printErrors();
return EXIT_FAILURE;
}
Model *model = document->getModel();
ListOfReactions *listOfReactions = model->getListOfReactions();
delete document;
return 0;
}
......@@ -56,6 +56,6 @@ delete_parameter(ParameterSet) :-
\+ (
member(Parameter, ParameterSet),
\+ (
delete_item([kind: parameter, key: ParameterSet])
delete_item([kind: parameter, key: Parameter])
)
).
......@@ -2,7 +2,9 @@
reaction_editor,
[
add_reaction/1,
add_reaction/4,
list_reactions/0,
reaction/5,
reaction/4,
simplify_all_reactions/0,
enumerate_molecules/1,
......@@ -13,11 +15,19 @@
add_reaction(Reaction) :-
biocham_command,
type(Reaction, reaction),
doc('adds reaction rules to the current set of reactions.'),
doc('
adds reaction rules to the current set of reactions.
This command is implicit: reaction rules can be added directly in models.
'),
simplify_reaction(Reaction, SimplifiedReaction),
add_item([kind: reaction, item: SimplifiedReaction]).
add_reaction(Kinetics, Left, Right, Reversible) :-
make_reaction(Kinetics, Left, Right, Reversible, Reaction),
add_reaction(Reaction).
list_reactions :-
biocham_command,
doc('lists the current set of reactions.'),
......@@ -142,14 +152,8 @@ coefficient_object(CoefficientObject, CoefficientObject).
simplify_reaction(Reaction, SimplifiedReaction) :-
reaction(Reaction, Kinetics, LeftMolecules, RightMolecules, Reversible),
simplify_kinetics(Kinetics, KineticsSimplified),
simplify_solution(LeftMolecules, LeftMoleculesSimplified),
simplify_solution(RightMolecules, RightMoleculesSimplified),
simplify_catalyst(
LeftMoleculesSimplified, RightMoleculesSimplified, Left, Catalyst, Right
),
build_reaction(
KineticsSimplified, Left, Catalyst, Right, Reversible, SimplifiedReaction
make_reaction(
Kinetics, LeftMolecules, RightMolecules, Reversible, SimplifiedReaction
).
......@@ -226,7 +230,17 @@ simplify_catalyst([Head | Tail], Right, NewLeft, Catalyst, NewRight) :-
).
build_reaction(Kinetics, Left, Catalyst, Right, Reversible, Reaction) :-
make_reaction(Kinetics, LeftMolecules, RightMolecules, Reversible, Reaction) :-
simplify_kinetics(Kinetics, KineticsSimplified),
simplify_solution(LeftMolecules, LeftSimplified),
simplify_solution(RightMolecules, RightSimplified),
simplify_catalyst(LeftSimplified, RightSimplified, Left, Catalyst, Right),
make_reaction(
KineticsSimplified, Left, Catalyst, Right, Reversible, Reaction
).
make_reaction(Kinetics, Left, Catalyst, Right, Reversible, Reaction) :-
(
Kinetics = 'MA'(1)
->
......
......@@ -2,22 +2,284 @@
reaction_graphs,
[
reaction_graph/0,
import_reactions_from_graph/0,
draw_reactions/0,
export_dot/1
]
).
:- devdoc('\\section{Commands}').
reaction_graph :-
biocham_command,
doc('').
doc('Builds the reaction graph of the current model.'),
new_graph,
set_graph_name(reaction_graph),
set_counter(reaction, 0),
\+ (
item([kind: reaction, item: Item]),
reaction(Item, Kinetics, Reactants, Products, Reversible),
\+ (
count(reaction, ReactionCount),
format(atom(ReactionCounter), 'reaction~d', [ReactionCount]),
transition(ReactionCounter),
(
Reversible = yes
->
set_attribute(ReactionCounter, reversible: Reversible)
;
true
),
(
Kinetics = 'MA'(1)
->
true
;
set_attribute(ReactionCounter, kinetics: Kinetics)
),
\+ (
(
member(Stochiometry * Object, Reactants),
From = Object,
To = ReactionCounter
;
member(Stochiometry * Object, Products),
From = ReactionCounter,
To = Object
),
\+ (
place(Object),
add_edge(From -> To),
(
get_attribute((From -> To), stochiometry: OldStochiometry)
->
NewStochiometry is OldStochiometry + Stochiometry
;
NewStochiometry is Stochiometry
),
(
NewStochiometry = 1
->
catch(
delete_attribute((From -> To), stochiometry),
error(unknown_item),
true
)
;
set_attribute((From -> To), stochiometry: NewStochiometry)
)
)
)
)
).
import_reactions_from_graph :-
biocham_command,
doc('
Updates the set of reactions of the current model with the current graph.
'),
make_bipartite_graph,
make_reactions.
draw_reactions :-
biocham_command,
doc('').
export_dot(InputFile) :-
biocham_command,
type(InputFile, input_file),
doc('').
:- dynamic(vertex_transition/1).
:- dynamic(vertex_place/1).
:- dynamic(fixpoint/0).
make_bipartite_graph :-
get_current_graph(GraphId),
retractall(vertex_transition(_)),
retractall(vertex_place(_)),
retractall(vertex_unknown(_)),
\+ (
item([parent: GraphId, kind: vertex, id: VertexId, item: Vertex]),
get_attribute(VertexId, kind: Kind),
\+ (
(
Kind = place
->
assertz(vertex_place(Vertex))
;
Kind = transition
->
assertz(vertex_transition(Vertex))
;
true
)
)
),
\+ \+ (
repeat,
assertz(fixpoint),
\+ (
item([parent: GraphId, kind: edge, item: (A -> B)]),
\+ (
reaction_object(A, B),
object_reaction(A, B),
reaction_object(B, A),
object_reaction(B, A)
)
),
fixpoint
),
check_bipartite_graph.
check_bipartite_graph :-
get_current_graph(GraphId),
findall(
AmbiguousVertex,
(
vertex_transition(AmbiguousVertex),
vertex_place(AmbiguousVertex)
),
AmbiguousVertices
),
(
AmbiguousVertices = []
->
true
;
throw(error(ambiguous_vertices(AmbiguousVertices)))
),
findall(
AmbiguousEdge,
(
item([parent: GraphId, kind: edge, item: AmbiguousEdge]),
AmbiguousEdge = (From -> _To),
\+ vertex_transition(From),
\+ vertex_place(From)
),
AmbiguousEdges
),
(
AmbiguousEdges = []
->
true
;
throw(error(ambiguous_edges(AmbiguousEdges)))
).
reaction_object(A, B) :-
(
vertex_transition(A),
\+ vertex_place(B)
->
assertz(vertex_place(B)),
retractall(fixpoint)
;
true
).
object_reaction(A, B) :-
(
vertex_place(A),
\+ vertex_transition(B)
->
assertz(vertex_transition(B)),
retractall(fixpoint)
;
true
).
make_reactions :-
delete_items([kind: reaction]),
get_current_graph(GraphId),
\+ (
vertex_transition(Reaction),
\+ (
get_kinetics(Reaction, Kinetics),
get_reversible(Reaction, Reversible),
findall(
Stochiometry * Reactant,
(
vertex_place(Reactant),
item([
parent: GraphId,
kind: edge,
item: (Reactant -> Reaction),
id: EdgeId
]),
get_stochiometry(EdgeId, Stochiometry)
),
Left
),
findall(
Stochiometry * Product,
(
vertex_place(Product),
item([
parent: GraphId,
kind: edge,
item: (Reaction -> Product),
id: EdgeId
]),
get_stochiometry(EdgeId, Stochiometry)
),
Right
),
add_reaction(Kinetics, Left, Right, Reversible)
)
).
get_kinetics(Vertex, Kinetics) :-
(