Commit 584ce8f3 authored by Thierry Martinez's avatar Thierry Martinez

Multi-models

parent b2a8559f
......@@ -3,7 +3,7 @@
:- begin_tests(aliases).
test('alias', [true(Rules == [2 * a => c])]) :-
new_model,
clear_model,
add_rule(a + b => c),
command(alias(a = b)),
all_items([model: current_model, kind: rule], Rules).
......
......@@ -11,7 +11,7 @@
:- 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),
......@@ -60,7 +60,12 @@ initialize_library_path :-
assertz(library_path(LibraryPath)).
biocham_command.
biocham_command :-
doc('Declares a command for the top-level.').
biocham_command(_).
biocham_command(_) :-
doc('
With a * : declares a command for the top-level that can take an
unlimited number of arguments.
The additional arguments are given as a list in the last parameter.').
......@@ -8,14 +8,23 @@
]
).
doc(_) :-
!,
true.
doc(_).
doc(_) :-
doc('
Writes in the documentation (both the Reference Manual
and the Developer Manual).
').
devdoc(_).
devdoc(_) :-
doc('Writes in the Developer Manual.').
grammar(_).
grammar(_) :-
doc('Declares a grammar predicate to be written in the documentation.').
generate_doc :-
......@@ -421,6 +430,16 @@ instantiate_grammar_body((G0, G1)) :-
instantiate_grammar_body(true) :-
!.
instantiate_grammar_body(list(Grammar, NonTerminal)) :-
!,
make_id(Grammar, Id),
format(
atom(NonTerminal), '
[</code> <a href="#~a">~a</a>
<code>,</code> ... <code>,</code>
<a href="#~a">~a</a> <code>] ', [Id, Grammar, Id, Grammar]
).
instantiate_grammar_body(Item) :-
Item =.. [Grammar, NonTerminal],
make_id(Grammar, Id),
......@@ -470,32 +489,14 @@ generate_body_item_clause(Clause, Stream, Type) :-
write(Stream, '.</code></h5>\n'),
\+ (
member(DocItem, Doc),
\+ (
write_doc_item(DocItem, Stream)
)
write_doc_item(DocItem, Stream, Type),
fail
)
;
true
).
collect_doc((biocham_command, Body)) :-
!,
collect_doc(Body).
collect_doc((type(Argument, Type), Body)) :-
!,
assertz(argument_type(Argument, Type)),
collect_doc(Body).
collect_doc((doc(DocBody), _)) :-
!,
nb_setval(doc_body, DocBody).
collect_doc(_) :-
!.
write_arguments([], _Doc) :-
!,
true.
......@@ -527,9 +528,20 @@ write_argument(Argument, Doc) :-
'<a href="#~a">~a</a><sub>1</sub> = <a href="#~a">~a</a><sub>1</sub>,
...,
<a href="#~a">~a</a><sub><var>n</var></sub> =
<a href="#~a">~a</a><sub><var>n</var></sub>,',
<a href="#~a">~a</a><sub><var>n</var></sub>',
[NameId, Name, ValueId, Value, NameId, Name, ValueId, Value]
)
;
Type = '*'([Name])
->
make_id(Name, NameId),
format(
Doc,
'[<a href="#~a">~a</a><sub>1</sub>],
...,
[<a href="#~a">~a</a><sub><var>n</var></sub>]',
[NameId, Name, NameId, Name]
)
;
Type = '='(ItemType)
->
......@@ -634,7 +646,11 @@ refer_argument(Argument, Doc) :-
).
write_doc_item(doc(DocBody), Stream) :-
write_doc_item(doc(DocBody), Stream, _Type) :-
write_doc(Stream, DocBody).
write_doc_item(devdoc(DocBody), Stream, devdoc) :-
write_doc(Stream, DocBody).
......@@ -657,6 +673,11 @@ write_doc_chars(['\\' | Tail], Doc) :-
write_command(Command, Argument, Doc),
write_doc_chars(TailDoc, Doc).
write_doc_chars(['-', '-', '-' | Tail], Doc) :-
!,
write(Doc, '&mdash;'),
write_doc_chars(Tail, Doc).
write_doc_chars(['-', '-' | Tail], Doc) :-
!,
write(Doc, '&ndash;'),
......@@ -667,6 +688,11 @@ write_doc_chars(['<' | Tail], Doc) :-
write(Doc, '&lt;'),
write_doc_chars(Tail, Doc).
write_doc_chars(['~' | Tail], Doc) :-
!,
write(Doc, '&nbsp;'),
write_doc_chars(Tail, Doc).
write_doc_chars([Char | Tail], Doc) :-
write(Doc, Char),
write_doc_chars(Tail, Doc).
......
......@@ -6,7 +6,7 @@ test(
'present',
[true(InitialState == [present(a), present(b)])]
) :-
new_model,
clear_model,
command(present({ a, b })),
all_items([model: current_model, kind: initial_state], InitialState).
......@@ -14,7 +14,7 @@ test(
'absent',
[true(InitialState == [absent(a), absent(b)])]
) :-
new_model,
clear_model,
command(absent({ a, b })),
all_items([model: current_model, kind: initial_state], InitialState).
......@@ -22,7 +22,7 @@ test(
'undefined',
[true(InitialState == [present(a), absent(b)])]
) :-
new_model,
clear_model,
command(present({ a, b, c })),
command(absent({ b, c, e })),
command(undefined({ c, d, e })),
......@@ -32,7 +32,7 @@ test(
'make_absent_not_present',
[true(InitialState == [present(a), absent(b)])]
) :-
new_model,
clear_model,
add_rule(a => b),
command(present(a)),
make_absent_not_present,
......@@ -42,7 +42,7 @@ test(
'make_present_not_absent',
[true(InitialState == [absent(a), present(b)])]
) :-
new_model,
clear_model,
add_rule(a => b),
command(absent(a)),
make_present_not_absent,
......
......@@ -6,7 +6,7 @@ test(
'set_macro',
[true(Macros == [macro(a = 1), macro(b = 3)])]
) :-
new_model,
clear_model,
command(set_macro(a = 1, b = 2)),
command(set_macro(b = 3)),
all_items([model: current_model, kind: macro], Macros).
......
......@@ -4,24 +4,37 @@
load/1,
load_biocham/1,
new_model/0,
clear_model/0,
get_model_name/1,
get_model_name/2,
set_model_name/1,
list_models/0,
select_model/1,
current_models/1,
single_model/1,
add_item/2,
add_item/3,
add_item/4,
replace_item/4,
set_annotation/3,
get_annotation/3,
delete_annotation/2,
item/1,
find_item/1,
all_items/2,
list_items/1,
delete_item/1
delete_item/1,
delete_items/1,
delete/1,
range/1
]
).
:- dynamic(fresh/0).
load(InputFile) :-
biocham_command,
type(InputFile, input_file),
......@@ -31,8 +44,7 @@ load(InputFile) :-
depending on the file extension
(respectively \\texttt{.bc}, \\texttt{.xml}, \\texttt{.ode}, \\texttt{.csv}
-- assuming no extension is \\texttt{.bc}).'),
new_model,
add(InputFile).
load_all(_Suffix, InputFile).
add(InputFile) :-
......@@ -44,31 +56,7 @@ add(InputFile) :-
depending on the file extension
(respectively \\texttt{.bc}, \\texttt{.xml}, \\texttt{.ode}, \\texttt{.csv}
-- assuming no extension is \\texttt{.bc}).'),
filename(InputFile, Filename),
chop_suffix(Filename, Suffix),
(
(
Suffix = '.bc'
;
Suffix = ''
)
->
add_biocham(Filename)
;
Suffix = '.xml'
->
add_sbml(Filename)
;
Suffix = '.ode'
->
add_ode(Filename)
;
Suffix = '.csv'
->
add_trace(Filename)
;
throw(error(unknown_suffix(Suffix)))
).
add_all(_Suffix, InputFile).
load_biocham(InputFile) :-
......@@ -80,17 +68,7 @@ load_biocham(InputFile) :-
contained in the given Biocham \\texttt{.bc} file.
The suffix \\texttt{.bc} is automatically added to the name if such a
file exists.'),
findall(
Id,
(
filename(InputFile, Filename),
new_model(Id),
set_model_name(Filename),
add_biocham_file(Filename)
),
CurrentModels
),
set_current_models(CurrentModels).
load_all('.bc', InputFile).
add_biocham(InputFile) :-
......@@ -101,14 +79,68 @@ add_biocham(InputFile) :-
\\emph{added} to the current set of rules.
The commands contained in the file are executed
(with the file directory as current directory).'),
add_all('.bc', InputFile).
load_all(Suffix, InputFile) :-
findall(
Id,
(
filename(InputFile, Filename),
chop_suffix(Filename, Suffix),
load(Suffix, Filename),
current_models(Ids),
member(Id, Ids)
),
CurrentModels
),
set_current_models(CurrentModels).
add_all(Suffix, InputFile) :-
\+ (
filename(InputFile, Filename),
\+ (
add_biocham_file(Filename)
(
var(Suffix)
->
chop_suffix(Filename, Suffix)
;
true
),
add(Suffix, Filename)
)
).
load(Bc, Filename) :-
(
Bc = '.bc'
;
Bc = ''
),
!,
new_model,
set_model_name(Filename),
add_biocham_file(Filename).
load(Suffix, _Filename) :-
throw(error(unknown_suffix(Suffix))).
add(Bc, Filename) :-
(
Bc = '.bc'
;
Bc = ''
),
!,
add_biocham_file(Filename).
add(Suffix, _Filename) :-
throw(error(unknown_suffix(Suffix))).
add_biocham_file(Filename) :-
automatic_suffix(Filename, '.bc', read, FilenameBc),
file_directory_name(FilenameBc, FileDirectory),
......@@ -141,6 +173,10 @@ load_biocham_stream(Stream) :-
).
current_models(Models) :-
nb_getval(current_models, Models).
set_current_models(Models) :-
nb_setval(current_models, Models).
......@@ -154,7 +190,7 @@ new_model :-
new_model(Id) :-
(
fresh,
nb_getval(current_models, [Id])
current_models([Id])
->
true
;
......@@ -166,18 +202,37 @@ new_model(Id) :-
list_models :-
biocham_command,
doc('lists all open models'),
list_items([model: top, kind: model]).
select_model(NameSet) :-
:- grammar(ref).
ref(Range) :-
list(range, Range).
ref(Name) :-
name(Name).
select_model(RefSet) :-
biocham_command,
type(NameSet, {name}),
type(RefSet, {ref}),
doc('selects some models.'),
findall(
Id,
(
member(Name, NameSet),
find_item([model: top, key: Name, id: Id])
member(Ref, RefSet),
(
list(Ref)
->
ranges_ids(Ref, Ids),
member(Id, Ids)
;
find_item([model: top, key: Ref, id: Id])
)
),
CurrentModels
),
......@@ -187,16 +242,30 @@ select_model(NameSet) :-
clear_model :-
biocham_command,
doc('clears the current model.'),
single_model(Model),
retractall(item(_, Model, _, _)).
current_models(CurrentModels),
\+ (
member(Id, CurrentModels),
\+ (
delete_item(Id)
)
).
get_model_name(Name) :-
single_model(Id),
get_model_name(Id, Name).
get_model_name(Id, Name) :-
find_item([model: top, id: Id, item: Name]).
set_model_name(Name) :-
biocham_command,
type(Name, name),
doc('changes the current model name.'),
single_model(Model),
replace_item(Model, model, Name, Name).
single_model(Id),
replace_item(Id, model, Name, Name).
not_fresh :-
......@@ -209,6 +278,20 @@ not_fresh :-
:- dynamic(key/2).
:- dynamic(annotation/3).
set_annotation(Id, Kind, Annotation) :-
retractall(annotation(Id, Kind, _)),
assertz(annotation(Id, Kind, Annotation)).
get_annotation(Id, Kind, Annotation) :-
annotation(Id, Kind, Annotation).
delete_annotation(Id, Kind) :-
retract(annotation(Id, Kind)).
add_item(Kind, Item) :-
add_item(Kind, [], Item).
......@@ -240,7 +323,7 @@ add_item(Model, Kind, Key, Item, Id) :-
single_model(Model) :-
(
nb_getval(current_models, [Model])
current_models([Model])
->
true
;
......@@ -271,13 +354,13 @@ item(Options) :-
(
var(Models)
->
nb_getval(current_models, Models),
current_models(Models),
member(Model, Models)
;
Models = current_models
->
nb_getval(current_models, AllModels),
member(Model, AllModels)
current_models(CurrentModels),
member(Model, CurrentModels)
;
member(Model, Models)
)
......@@ -288,6 +371,11 @@ item(Options) :-
var(Key)
->
true
;
list(Key)
->
indexes_ids(Key, Ids),
member(Id, Ids)
;
key(Key, Id)
),
......@@ -319,29 +407,132 @@ optional(Item, List) :-
).
:- dynamic(listed_item/2).
list_items(Options) :-
retractall(listed_item(_, _)),
set_counter(list_item_counter, 0),
\+ (
item([item: Item | Options]),
item([item: Item, id: Id | Options]),
count(list_item_counter, Counter),
\+ (
assertz(listed_item(Counter, Id)),
format('[~d] ~w\n', [Counter, Item])
)
).
delete_item(Id) :-
delete_item(Id, _Model).
retract(item(Id, _Model, KindItem, _Item)),
retractall(key(_Key, Id)),
retractall(annotation(Id, _KindAnnotation, _Annotation)),
retractall(listed_item(_Index, Id)),
(
KindItem = model
->
\+ (
item(SubId, Id, _SubKind, _SubItem),
\+ (
delete_item(SubId)
)
),
current_models(CurrentModels),
(
select(Id, CurrentModels, OtherModels)
->
nb_setval(current_models, OtherModels),
(
OtherModels = []
->
new_model
;
true
)
;
true
)
;
true
).
delete_item(Id, Model) :-
retract(item(Id, Model, _Kind, _Item)),
retractall(key(_Key, Id)).
delete_items(Options) :-
\+ (
item([id: Id | Options]),
\+ (
delete_item(Id)
)
).
:- grammar(range).
range(Integer0 - Integer1) :-
integer(Integer0),
integer(Integer1).
range(Integer) :-
integer(Integer).
delete(Indexes) :-
biocham_command(*),
type(Indexes, '*'([range])),
doc('deletes the listed elements from the model.'),
indexes_ids(Indexes, Ids),
\+ (
member(Id, Ids),
\+ (
delete_item(Id)
)
).
indexes_ids(Indexes, Ids) :-
findall(
Id,
(
member(Ranges, Indexes),
ranges_ids(Ranges, RangeIds),
member(Id, RangeIds)
),
Ids
).
ranges_ids(Ranges, Ids) :-
findall(
Id,
(
member(Range, Ranges),
(
Range = Min - Max
->
between(Min, Max, Range)
;
Index = Range
),
resolve_index(Index, Id)
),
Ids
).
resolve_index(Index, Id) :-
(
listed_item(Index, Id)
->
true
;
throw(error(no_such_element, Index))
).
replace_item(Id, Kind, Key, Item) :-
delete_item(Id, Model),
retract(item(Id, Model, _Kind, _Item)),
retractall(key(_Key, Id)),
add_item(Model, Kind, Key, Item, Id).
create_item_id(Id) :-
count(item_id, Id).
......@@ -5,9 +5,20 @@
test('new_model', [true(Rules == [])]) :-
new_model,
single_model(Id0),
add_rule(a => b),
new_model,
all_items([model: current_model, kind: rule], Rules).
single_model(Id1),
all_items([model: current_model, kind: rule], Rules),
delete_item(Id0),
delete_item(Id1).
test('load', [true(Name == 'examples/mapk/mapk')]) :-
command(load(examples/mapk/mapk)),
single_model(Id),
get_model_name(Id, Name),
delete_item(Id).
:- end_tests(models).
......@@ -4,7 +4,7 @@
test('mapk') :-
new_model,
clear_model,
command(load(examples/mapk/mapk)),
numerical_simulation.
......
......@@ -3,7 +3,7 @@
:- begin_tests(nusmv).
test('nusmv') :-
new_model,
clear_model,
add_rule(a => b),
add_rule(a + b => c),
command(present(a)),
......
......@@ -13,6 +13,7 @@
set_parameter(ParameterList) :-
biocham_command(*),
type(ParameterList, '*'(parameter = number)),
print(ParameterList), nl,
doc('sets the value of parameters.'),
\+ (
member(Parameter = Value, ParameterList),
......
......@@ -6,7 +6,7 @@ test(
'set_parameter',
[true(Parameters == [parameter(a = 1), parameter(b = 3)])]
) :-
new_model,
clear_model,
command(set_parameter(a = 1, b = 2)),
command(set_parameter(b = 3)),
all_items([model: current_model, kind: parameter], Parameters).
......
......@@ -5,12 +5,12 @@
test('compound', [true(Rules == [2 * a + 2 * b => 2 * 'a-b'])]) :-
new_model,
clear_model,
command(add_rule(2 * a + 2 * b => 2 * a-b)),
all_items([model: current_model, kind: rule], Rules).
test('catalyst', [true(Rules == [2 * b <=[ a + c ]=> b])]) :-
new_model,
clear_model,
add_rule(a + b + c <=[ b ]=> a + c),
all_items([model: current_model, kind: rule], Rules).
......
......@@ -42,6 +42,8 @@
- rule_editor.pl
- rule_editor.plt