Commit 8f2f150b authored by Thierry Martinez's avatar Thierry Martinez

Grammars

parent 3931244a
......@@ -10,13 +10,12 @@
).
alias(Objects) :-
alias(ObjectList) :-
biocham_command,
type(Objects, =([object])),
type(ObjectList, =(object)),
doc('
makes \\argument{Objects} be alternative names for the
same object.'),
equals_to_list(Objects, ObjectList),
setof(
Object,
instance_member_delete(Object, ObjectList),
......
......@@ -5,7 +5,7 @@
test('alias', [true(Rules == [2 * a => c])]) :-
new_model,
add_rule(a + b => c),
alias(a = b),
command(alias(a = b)),
all_items([model: current_model, kind: rule], Rules).
:- end_tests(aliases).
......@@ -3,8 +3,7 @@
[
start/0,
initialize/0,
biocham_command/0,
biocham_command/1
biocham_command/0
]).
......@@ -21,8 +20,3 @@ initialize :-
biocham_command.
biocham_command(Functor/Arity) :-
functor(Head, Functor, Arity),
once(clause(Head, (biocham_command, _))).
......@@ -2,6 +2,7 @@
doc,
[
doc/1,
grammar/1,
generate_doc/0
]
).
......@@ -10,6 +11,9 @@
doc(_).
grammar(_).
generate_doc :-
generate_doc(doc),
generate_doc(devdoc).
......@@ -306,7 +310,7 @@ generate_body_item(file(File), Doc, Type) :-
generate_body_item(index, Doc, _Type) :-
\+ (
bag_of(Entry, index_entry(Letter, Entry), Entries),
bagof(Entry, index_entry(Letter, Entry), Entries),
\+ (
format(Doc, '<h4>~a</h4>\n', [Letter]),
write(Doc, '<ul>\n'),
......@@ -315,18 +319,10 @@ generate_body_item(index, Doc, _Type) :-
\+ (
format(Doc, '<li>~a ', [Key]),
\+ (
nth1(Index, Sections, Section),
member(Section - Id, Sections),
\+ (
(
Index = 1
->
Name = Key
;
format(atom(Name), '~a-~d', [Key, Index])
),
make_id(Name, Id),
format(Doc, '<a href="#~a">', [Id]),
write_counters(Section),
write_counters(Doc, Section),
write(Doc, '</a>')
)
),
......@@ -348,6 +344,7 @@ generate_body_item(bibliography, _Doc, _Type) :-
generate_body_item_stream(Stream, Doc, Type) :-
nb_setval(current_grammar, none),
\+ (
repeat,
read_term(
......@@ -356,8 +353,34 @@ generate_body_item_stream(Stream, Doc, Type) :-
(
Clause = end_of_file
->
close_grammar(Doc),
!
;
Clause = (:- grammar(Grammar))
->
close_grammar(Doc),
nb_setval(current_grammar, Grammar),
make_id(Grammar, Id),
format(
Doc,
'<table id="~a"><tr><td>~a ::= </td><td>\n',
[Id, Grammar]
)
;
nb_getval(current_grammar, Grammar),
Grammar \= none,
(
Clause = (Head :- Body)
;
Clause = Head,
Body = true
),
Head =.. [Grammar, Item]
->
instantiate_grammar_body(Body),
format(Doc, '<div>| <code>~w</code></div>', [Item])
;
close_grammar(Doc),
name_variables_and_anonymous(Variables, VariableNames),
generate_body_item_clause(Clause, Doc, Type)
),
......@@ -365,33 +388,72 @@ generate_body_item_stream(Stream, Doc, Type) :-
).
close_grammar(Stream) :-
nb_getval(current_grammar, Grammar),
(
Grammar = none
->
true
;
nb_setval(current_grammar, none),
write(Stream, '</td></tr></table>\n')
).
instantiate_grammar_body((G0, G1)) :-
!,
instantiate_grammar_body(G0),
instantiate_grammar_body(G1).
instantiate_grammar_body(true) :-
!.
instantiate_grammar_body(Item) :-
Item =.. [Grammar, NonTerminal],
make_id(Grammar, Id),
format(
atom(NonTerminal), ' </code> <a href="#~a">~a</a> <code> ', [Id, Grammar]
).
:- dynamic(argument_type/2).
generate_body_item_clause(Clause, Doc, Type) :-
Clause = (Head :- Body),
nb_setval(doc_body, undocumented),
collect_doc(Body),
nb_getval(doc_body, DocBody),
generate_body_item_clause(Clause, Stream, Type) :-
predicate_info(Clause, ArgumentTypes, BiochamCommand, Doc),
(
(
Body = (biocham_command, _)
BiochamCommand = yes
;
Type = devdoc,
DocBody \= undocumented
Doc \= []
)
->
Clause = (Head :- _),
Head =.. [Command | Arguments],
retractall(argument_type(_, _)),
\+ (
nth0(Index, Arguments, Argument),
nth0(Index, ArgumentTypes, ArgumentType),
nonvar(ArgumentType),
\+ (
assertz(argument_type(Argument, ArgumentType))
)
),
make_id(Command, CommandId),
length(Arguments, Arity),
format(atom(Key), '~a/~d', [Command, Arity]),
format(atom(Id), '~a-~d', [CommandId, Arity]),
index_use_id(Key, Id),
format(Doc, '<h5 id="~a""><code>~a', [Id, Command]),
write_arguments(Arguments, Doc),
write(Doc, '.</code></h5>\n'),
write_doc(Doc, DocBody)
format(Stream, '<h5 id="~a""><code>~a', [Id, Command]),
write_arguments(Arguments, Stream),
write(Stream, '.</code></h5>\n'),
\+ (
member(DocItem, Doc),
\+ (
write_doc_item(DocItem, Stream)
)
)
;
true
).
......@@ -436,36 +498,59 @@ write_argument(Argument, Doc) :-
argument_type(Argument, Type)
->
(
Type = '='([ItemType])
Type = '='(ItemType)
->
make_id(ItemType, Id),
format(
Doc,
'~a<sub>1</sub> = ... = ~a<sub><var>n</var></sub>',
[ItemType, ItemType]
'<a href="#~a">~a</a><sub>1</sub> = ... =
<a href="#~a">~a</a><sub><var>n</var></sub>',
[Id, ItemType, Id, ItemType]
)
;
write_argument_type(Argument, Type, Doc)
Type = {ItemType}
->
make_id(ItemType, Id),
format(
Doc,
'{<a href="#~a">~a</a><sub>1</sub>, ...,
<a href="#~a">~a</a><sub><var>n</var></sub>}',
[Id, ItemType, Id, ItemType]
)
;
Type = [ItemType]
->
make_id(ItemType, Id),
format(
Doc,
'[<a href="#~a">~a</a><sub>1</sub>, ...,
<a href="#~a">~a</a><sub><var>n</var></sub>]',
[Id, ItemType, Id, ItemType]
)
;
camel_case(Type, CamelCaseType),
(
Argument = CamelCaseType
->
make_id(Type, Id),
format(Doc, '<a href="#~a">~a</a>', [Id, Type])
;
atom_concat(CamelCaseType, Suffix, Argument)
->
make_id(Type, Id),
format(
Doc,
'<a href="#~a">~a</a><sub><var>~a</var></sub>',
[Id, Type, Suffix]
)
;
format(Doc, '<var>~a</var>: ~a', [Argument, Type])
)
)
;
write_var(Doc, Argument)
).
write_argument_type(Argument, Type, Doc) :-
camel_case(Type, CamelCaseType),
(
Argument = CamelCaseType
->
format(Doc, '~a', [Type])
;
atom_concat(CamelCaseType, Suffix, Argument)
->
format(Doc, '~a<sub><var>~a</var></sub>', [Type, Suffix])
;
format(Doc, '<var>~a</var>', [Argument])
).
write_var(Doc, Var) :-
format(Doc, '<var>~a</var>', [Var]).
......@@ -475,21 +560,50 @@ refer_argument(Argument, Doc) :-
argument_type(Argument, Type)
->
(
Type = '='([ItemType])
(
Type = '='(ItemType)
;
Type = [ItemType]
;
Type = {ItemType}
)
->
make_id(ItemType, Id),
format(
Doc,
'~a<sub>1</sub>, ..., ~a<sub><var>n</var></sub>',
[ItemType, ItemType]
'<a href="#~a">~a</a><sub>1</sub>, ...,
<a href="#~a">~a</a><sub><var>n</var></sub>',
[Id, ItemType, Id, ItemType]
)
;
write_argument_type(Argument, Type, Doc)
camel_case(Type, CamelCaseType),
(
Argument = CamelCaseType
->
make_id(Type, Id),
format(Doc, '<a href="#~a">~a</a>', [Id, Type])
;
atom_concat(CamelCaseType, Suffix, Argument)
->
make_id(Type, Id),
format(
Doc,
'<a href="#~a">~a</a><sub><var>~a</var></sub>',
[Id, Type, Suffix]
)
;
format(Doc, '<var>~a</var>', [Argument])
)
)
;
write_var(Doc, Argument)
).
write_doc_item(doc(DocBody), Stream) :-
write_doc(Stream, DocBody).
write_doc(Doc, DocBody) :-
atom_chars(DocBody, DocChars),
write_doc_chars(DocChars, Doc),
......@@ -567,9 +681,11 @@ write_command(Command, _Argument, _Doc) :-
:- dynamic(index_contents/2).
index_entry(Letter, Key: Sections) :-
index_entry(UppercaseLetter, Key: Sections) :-
index_contents(Key, Sections),
atom_chars(Key, [Letter | _]).
atom_chars(Key, [Letter | _]),
to_upper(Letter, UpperCode),
atom_codes(UppercaseLetter, [UpperCode]).
index(Doc, Key) :-
......@@ -591,7 +707,7 @@ index_new_id(Key, Id) :-
),
make_id(Name, Id),
append(List, [Counters - Id], NewList),
assertz(index(Key, NewList)).
assertz(index_contents(Key, NewList)).
index_use_id(Key, Id) :-
......@@ -604,4 +720,4 @@ index_use_id(Key, Id) :-
List = []
),
append(List, [Counters - Id], NewList),
assertz(index(Key, NewList)).
assertz(index_contents(Key, NewList)).
......@@ -9,20 +9,10 @@
filename(Filename, ExpandedFilename) :-
flat_filename(Filename, FlatFilename),
expand_file_name(FlatFilename, List),
expand_file_name(Filename, List),
member(ExpandedFilename, List).
flat_filename('.'(Prefix, Suffix), Filename) :-
!,
flat_filename(Prefix, PrefixAtom),
flat_filename(Suffix, SuffixAtom),
format(atom(Filename), '~a.~a', [PrefixAtom, SuffixAtom]).
flat_filename(Filename, Filename).
chop_suffix(Filename, Suffix) :-
atom_chars(Filename, Chars),
(
......@@ -33,7 +23,7 @@ chop_suffix(Filename, Suffix) :-
->
atom_chars(Suffix, ['.' | SuffixChars])
;
Suffix = Filename
Suffix = ''
).
......@@ -42,7 +32,7 @@ automatic_suffix(Filename, DefaultSuffix, FullFilename) :-
(
Suffix = '',
atom_concat(Filename, DefaultSuffix, FullFilename),
file_exists(FullFilename)
exists_file(FullFilename)
->
true
;
......
......@@ -7,7 +7,9 @@
present/1,
present/2,
absent/1,
undefined/1
undefined/1,
make_absent_not_present/0,
make_present_not_absent/0
]
).
......@@ -51,85 +53,98 @@ clear_initial_state :-
).
present(Object) :-
present(ObjectSet) :-
biocham_command,
type(Object, object),
doc('\\argument{Object} is made present in the initial state.'),
undefined_no_error(Object),
add_item(initial_state, Object, present(Object)).
type(ObjectSet, {object}),
doc('
Every object in \\argument{ObjectSet} is made present in the initial
state.'),
set_state(ObjectSet, Object, present(Object)).
present(Object, Concentration) :-
present(ObjectSet, Concentration) :-
biocham_command,
type(Object, object),
type(ObjectSet, {object}),
type(Concentration, concentration),
doc('
\\argument{Object} is initialized with the given initial concentration.
Every object in \\argument{ObjectSet} is initialized
with the given initial concentration.
An initial value equal to 0 means absent.'),
undefined_no_error(Object),
add_item(initial_state, Object, present(Object, Concentration)).
set_state(ObjectSet, Object, present(Object, Concentration)).
absent(Object) :-
absent(ObjectSet) :-
biocham_command,
type(Object, object),
doc('\\argument{Object} is made absent in the initial state.'),
catch(
undefined(Object),
error(unknown_initial_state(_)),
true
),
add_item(initial_state, Object, absent(Object)).
type(ObjectSet, {object}),
doc('
Every object in \\argument{ObjectSet} is made absent in the initial
state.'),
set_state(ObjectSet, Object, absent(Object)).
undefined_no_error(Object) :-
catch(
undefined(Object),
error(unknown_initial_state(_)),
true
set_state(ObjectSet, Object, State) :-
\+ (
member(Object, ObjectSet),
\+ (
undefined_object(Object),
add_item(initial_state, Object, State)
)
).
undefined(Object) :-
undefined(ObjectSet) :-
biocham_command,
type(Object, object),
type(ObjectSet, {object}),
doc('
\\argument{Object} is made possibly present or absent in the initial
state.'),
Every object in \\argument{ObjectSet} is made possibly present or absent
in the initial state.'),
\+ (
member(Object, ObjectSet),
\+ (
undefined_object(Object)
)
).
undefined_object(Object) :-
(
item([model: current_model, kind: initial_state, key: Object, id: Id])
->
delete_item(Id)
;
throw(error(unknown_initial_state(Object)))
true
).
/*
list_initial_state .
lists the objects which are present (including their initial concentration) and absent from the initial state.
• list_all_initial_states .
same as above but lists undefined objects as well.
• clear_initial_state .
makes undefined all objects possibly present or absent in the initial state. Also deletes all parameters and macros.
• present(object_pattern) .
• present(set_of_object_patterns) .
all objects (appearing in the instances of the current set of rules) and matching one of the given object patterns are made present in the initial state.
Example 24 present({cycA, cdk1, cycE~?}). makes cycA, cdk1 and all modified forms of cycE present in the initial state.
• present(object_pattern,concentration) .
• present(object_pattern,parameter) .
initializes the given objects with the given initial concentration, or sets it to be equal to the value of the given parameter. An initial value equal to 0 means absent.
Example 25
present(MAPK,0.3). present(CycE, k).
makes present two molecules with concentration, respectively 0.3 and the value of parameter k.
• absent(object_pattern) . • absent(set_of_object_patterns) .
makes all objects (appearing in the instances of the current set of rules) and matching one of the given object patterns, absent from the initial state. Same as present with initial concentration equal to 0.
• undefined(object_pattern) . • undefined(set_of_object_patterns) .
makes all objects (appearing in the instances of the current set of rules) and matching one of the given object patterns, possibly present or absent in the initial state.
• make_present_not_absent .
makes all objects (appearing in the instances of the current set of rules) which are not declared absent, present in the initial state.
• make_absent_not_present .
makes all objects (appearing in the instances of the current set of rules) which are not declared present, absent in the initial state.
• set_initial_state(state) .
• set_initial_state(set_of_states) .
*/
make_present_not_absent :-
biocham_command,
doc('
makes all objects (appearing in the instances of the current set of rules)
which are not declared absent, present in the initial state.'),
enumerate_molecules(Objects),
\+ (
member(Object, Objects),
\+ defined(Object),
\+ (
present([Object])
)
).
make_absent_not_present :-
biocham_command,
doc('
makes all objects (appearing in the instances of the current set of rules)
which are not declared present, absent in the initial state.'),
enumerate_molecules(Objects),
\+ (
member(Object, Objects),
\+ defined(Object),
\+ (
absent([Object])
)
).
defined(Object) :-
once(item([model: current_model, kind: initial_state, key: Object])).
:- module(
macros,
[
macro/2,
macro/1,
set_macro/2,
set_macro/1,
list_macros/0,
delete_macro/1
]
).
macro(Macro, Value) :-
set_macro(Macro, Value) :-
biocham_command,
type(Macro, macro),
doc('sets the value of \\argument{macro} to \\argument{Value}.'),
......@@ -20,7 +20,7 @@ macro(Macro, Value) :-
add_item(macro, Macro, macro(Macro, Value)).
macro(Macro) :-
set_macro(Macro) :-
biocham_command,
type(Macro, macro),
doc('shows the expression associated to the given macro.'),
......
......@@ -94,8 +94,8 @@ add_biocham(InputFile) :-
file_directory_name(FilenameBc, FileDirectory),
setup_call_cleanup(
(
working_directory(FileDirectory, PreviousDirectory),
open(FilenameBc, read, Stream)
open(FilenameBc, read, Stream),
working_directory(PreviousDirectory, FileDirectory)
),
load_biocham_stream(Stream),
(
......@@ -114,13 +114,12 @@ load_biocham_stream(Stream) :-
(
Command = end_of_file
->
!,
fail
!
;
name_vars_and_anonymous(Command, VariableNames),
execute_command(Command),
fail
)
name_variables_and_anonymous(Command, VariableNames),
execute_command(Command)
),
fail
).
......@@ -149,13 +148,13 @@ clear_model :-
retractall(item(_, Model, _, _)).
set_model_name(ModelName) :-
set_model_name(Name) :-
biocham_command,
type(ModelName, model_name),
type(Name, name),
doc('changes the current model name.'),
single_model(Model),
retractall(name(Model, _)),
assertz(name(Model, ModelName)).
assertz(name(Model, Name)).
not_fresh :-
......
......@@ -2,10 +2,16 @@
:- begin_tests(models).
test('new_model', [true(Rules == [])]) :-
new_model,
add_rule(a => b),
new_model,
all_items([model: current_model, kind: rule], Rules).
test('mapk') :-
new_model,
command(load(examples/mapk/mapk)).
:- end_tests(models).
:- module(
objects,
[
rule/1,
op(800, xfx, for),
op(700, xfx, <=),
op(750, xfx, =>),
op(750, xfx, <=>),
op(700, xfy, =)
input_file/1,
concentration/1,
name/1,
parameter/1,
macro/1,
object/1,
op(100, xfy, '~')
]
).
rule(_ for _).
rule(_ => _).
:- grammar(input_file).
rule(_ <=> _).
input_file(Name) :-
atom(Name).
:- grammar(concentration).
concentration(Number) :-
number(Number).
:- grammar(time).
time(Number) :-
number(Number).
:- grammar(name).
name(Name) :-
atom(Name).
:- grammar(parameter).
parameter(Name) :-
atom(Name).
:- grammar(macro).
macro(Name) :-
atom(Name).
:- grammar(object).