Commit 3931244a authored by Thierry Martinez's avatar Thierry Martinez

Index and bibliography

parent 88806fdd
......@@ -2,8 +2,10 @@
aliases,
[
alias/1,
list_parameters/0,
delete_parameter/1
canonical/1,
canonical/2,
list_aliases/0,
delete_alias/1
]
).
......@@ -15,41 +17,79 @@ alias(Objects) :-
makes \\argument{Objects} be alternative names for the
same object.'),
equals_to_list(Objects, ObjectList),
setof(
add_item(parameter, parameter(Parameter, Value)).
setof(
Object,
instance_member_delete(Object, ObjectList),
EquivalenceClassList),
add_equivalence_class_list(EquivalenceClassList).
add_equivalence_class_list(EquivalenceClassList) :-
(
EquivalenceClassList = [_]
->
true
;
list_to_equals(EquivalenceClassList, EquivalenceClass),
add_item(alias, EquivalenceClassList, alias(EquivalenceClass)),
simplify_all_rules
).
parameter(Parameter) :-
biocham_command,
type(Parameter, parameter),
doc('shows the value of \\argument{Parameter}.'),
find_parameter(Parameter, _Id, Value),
write(Value),
nl.
instance_member_delete(Object, ObjectList) :-
member(Instance, ObjectList),
catch(
(
find_alias(Instance, Id, EquivalenceClassList),
delete_item(Id),
member(Object, EquivalenceClassList)
),
error(not_an_alias(_)),
Object = Instance
).
find_parameter(Parameter, Id, Value) :-
find_alias(Instance, Id, EquivalenceClassList) :-
(
item(
[model: current_model, kind: macro, id: Id],
parameter(Parameter, Value)
)
item([id: Id, kind: alias, key: Instance, item: alias(EquivalenceClass)]),
equals_to_list(EquivalenceClass, EquivalenceClassList)
->
true
;
throw(error(undefined_parameter(Parameter)))
throw(error(not_an_alias(Instance)))
).
canonical(Object) :-
biocham_command,
type(Object, object),
doc('
makes \\argument{Object} be the canonical representant
for all its aliases.'),
find_alias(Object, Id, EquivalenceClassList),
delete_item(Id),
delete(EquivalenceClassList, Object, RemainingClassList),
add_equivalence_class_list([Object | RemainingClassList]).
canonical(Object, Canonical) :-
catch(
find_alias(Object, _, [Canonical | _]),
error(not_an_alias(_)),
Canonical = Object
).
list_parameters :-
list_aliases :-
biocham_command,
doc('shows the values of all known parameters.'),
list_items([model: current_model, kind: parameter]).
doc('shows the values of all known aliases.'),
list_items([model: current_model, kind: alias]).
delete_parameter(Parameter) :-
delete_alias(Object) :-
biocham_command,
type(Parameter, parameter),
doc('deletes a parameter'),
find_parameter(Parameter, Id, _Value),
delete_item(Id).
type(Object, object),
doc('makes \\argument{Object} distinct from all other objects.'),
find_alias(Object, Id, EquivalenceClassList),
delete_item(Id),
delete(EquivalenceClassList, Object, RemainingClassList),
add_equivalence_class_list(RemainingClassList).
:- use_module(library(plunit)).
:- begin_tests(aliases).
test('alias', [true(Rules == [2 * a => c])]) :-
new_model,
add_rule(a + b => c),
alias(a = b),
all_items([model: current_model, kind: rule], Rules).
:- end_tests(aliases).
......@@ -11,21 +11,28 @@ doc(_).
generate_doc :-
generate_doc(doc),
generate_doc(devdoc).
generate_doc(Type) :-
catch(
make_directory('doc'),
make_directory(Type),
error(existence_error(directory, _), _),
true
),
format(atom(IndexFilename), '~a/index.html', [Type]),
setup_call_cleanup(
open('doc/index.html', write, Stream),
generate_doc(Stream),
open(IndexFilename, write, Stream),
generate_doc(Stream, Type),
close(Stream)
).
generate_doc(Doc) :-
generate_doc(Doc, Type) :-
version(Version),
format(atom(Title), 'Biocham ~a Reference Manual', [Version]),
doc_title(Type, DocTitle),
format(atom(Title), 'Biocham ~a ~a', [Version, DocTitle]),
format(Doc, '\c
<!DOCTYPE html>
<html>
......@@ -35,19 +42,25 @@ generate_doc(Doc) :-
<body>
<h1>~a</h1>
', [Title, Title]),
generate_toc(Doc),
generate_body(Doc),
generate_toc(Doc, Type),
generate_body(Doc, Type),
write(Doc, '
</body>
</html>').
doc_title(doc, 'Reference Manual').
doc_title(devdoc, 'Developer Manual').
:- dynamic(toc/1).
generate_toc(Doc) :-
generate_toc(Doc, Type) :-
retractall(toc(_)),
read_toc,
nb_setval(last_level, 0),
read_toc(Type),
write(Doc, ' <h2 id="Contents">Contents</h2>\n'),
nb_setval(current_counters, []),
\+ (
......@@ -142,6 +155,9 @@ increment_counter :-
write_counters(Doc) :-
nb_getval(current_counters, Counters),
write_counters(Doc, Counters).
write_counters(Doc, Counters) :-
\+ (
member(Counter, Counters),
\+ (
......@@ -187,15 +203,15 @@ filter_id([_ | Tail], Id) :-
filter_id(Tail, Id).
read_toc :-
read_toc(Type) :-
setup_call_cleanup(
open('toc.org', read, Stream),
read_toc(Stream),
read_toc(Stream, Type),
close(Stream)
).
read_toc(Stream) :-
read_toc(Stream, Type) :-
\+ (
repeat,
read_line_to_codes(Stream, Line),
......@@ -208,18 +224,36 @@ read_toc(Stream) :-
(
atom_concat('* ', Section, Atom)
->
assertz(toc(section(1, Section)))
add_section(1, Section)
;
atom_concat('** ', Section, Atom)
->
assertz(toc(section(2, Section)))
add_section(2, Section)
;
atom_concat('*** ', Section, Atom)
->
assertz(toc(section(3, Section)))
add_section(3, Section)
;
Atom = '+ index'
->
assertz(toc(index))
;
Atom = '- biocham.bib'
->
assertz(toc(bibliography))
;
atom_concat('- ', File, Atom)
->
(
Type = devdoc,
atom_concat(_, '.pl', File)
->
nb_getval(last_level, Level),
LevelSucc is Level + 1,
add_section_nolevel(LevelSucc, File)
;
true
),
assertz(toc(file(File)))
)
),
......@@ -227,17 +261,26 @@ read_toc(Stream) :-
).
generate_body(Doc) :-
add_section(Level, Section) :-
add_section_nolevel(Level, Section),
nb_setval(last_level, Level).
add_section_nolevel(Level, Section) :-
assertz(toc(section(Level, Section))).
generate_body(Doc, Type) :-
retractall(index_contents(_, _)),
nb_setval(current_counters, []),
\+ (
toc(Item),
\+ (
generate_body_item(Item, Doc)
generate_body_item(Item, Doc, Type)
)
).
generate_body_item(section(Level, Title), Doc) :-
generate_body_item(section(Level, Title), Doc, _Type) :-
goto_level(Level),
increment_counter,
make_id(Title, Id),
......@@ -254,15 +297,57 @@ generate_body_item(section(Level, Title), Doc) :-
).
generate_body_item(file(File), Doc) :-
generate_body_item(file(File), Doc, Type) :-
setup_call_cleanup(
open(File, read, Stream),
generate_body_item_stream(Stream, Doc),
generate_body_item_stream(Stream, Doc, Type),
close(Stream)
).
generate_body_item(index, Doc, _Type) :-
\+ (
bag_of(Entry, index_entry(Letter, Entry), Entries),
\+ (
format(Doc, '<h4>~a</h4>\n', [Letter]),
write(Doc, '<ul>\n'),
\+ (
member((Key: Sections), Entries),
\+ (
format(Doc, '<li>~a ', [Key]),
\+ (
nth1(Index, Sections, Section),
\+ (
(
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(Doc, '</a>')
)
),
write(Doc, '</li>\n')
)
),
write(Doc, '</ul>\n')
)
).
generate_body_item_stream(Stream, Doc) :-
generate_body_item(bibliography, _Doc, _Type) :-
true.
% setup_call_cleanup(
% open('biocham.bib', read, Stream),
% generate_body_item_stream(Stream, Doc, Type),
% close(Stream)
% ).
generate_body_item_stream(Stream, Doc, Type) :-
\+ (
repeat,
read_term(
......@@ -274,7 +359,7 @@ generate_body_item_stream(Stream, Doc) :-
!
;
name_variables_and_anonymous(Variables, VariableNames),
generate_body_item_clause(Clause, Doc)
generate_body_item_clause(Clause, Doc, Type)
),
fail
).
......@@ -283,26 +368,39 @@ generate_body_item_stream(Stream, Doc) :-
:- dynamic(argument_type/2).
generate_body_item_clause(Clause, Doc) :-
generate_body_item_clause(Clause, Doc, Type) :-
Clause = (Head :- Body),
nb_setval(doc_body, undocumented),
collect_doc(Body),
nb_getval(doc_body, DocBody),
(
Clause = (Head :- biocham_command, Body)
(
Body = (biocham_command, _)
;
Type = devdoc,
DocBody \= undocumented
)
->
Head =.. [Command | Arguments],
retractall(argument_type(_, _)),
nb_setval(doc_body, undocumented),
collect_doc(Body),
make_id(Command, Id),
make_id(Command, CommandId),
length(Arguments, Arity),
format(Doc, '<h5 id="~a-~d""><code>~a', [Id, Arity, Command]),
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'),
nb_getval(doc_body, DocBody),
write_doc(Doc, DocBody)
;
true
).
collect_doc((biocham_command, Body)) :-
!,
collect_doc(Body).
collect_doc((type(Argument, Type), Body)) :-
!,
assertz(argument_type(Argument, Type)),
......@@ -337,20 +435,58 @@ write_argument(Argument, Doc) :-
(
argument_type(Argument, Type)
->
camel_case(Type, CamelCaseType),
(
Argument = CamelCaseType
Type = '='([ItemType])
->
format(Doc, '~a', [Type])
format(
Doc,
'~a<sub>1</sub> = ... = ~a<sub><var>n</var></sub>',
[ItemType, ItemType]
)
;
atom_concat(CamelCaseType, Suffix, Argument)
write_argument_type(Argument, Type, Doc)
)
;
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]).
refer_argument(Argument, Doc) :-
(
argument_type(Argument, Type)
->
(
Type = '='([ItemType])
->
format(Doc, '~a<sub><var>~a</var></sub>', [Type, Suffix])
format(
Doc,
'~a<sub>1</sub>, ..., ~a<sub><var>n</var></sub>',
[ItemType, ItemType]
)
;
format(Doc, '<var>~a</var>', [Argument])
write_argument_type(Argument, Type, Doc)
)
;
format(Doc, '<var>~a</var>', [Argument])
write_var(Doc, Argument)
).
......@@ -408,7 +544,7 @@ write_command(command, Command, Doc) :-
write_command(argument, Argument, Doc) :-
!,
write(Doc, '<code>'),
write_argument(Argument, Doc),
refer_argument(Argument, Doc),
write(Doc, '</code>').
write_command(emph, Argument, Doc) :-
......@@ -418,5 +554,54 @@ write_command(emph, Argument, Doc) :-
write_doc_chars(ArgumentChars, Doc),
write(Doc, '</em>').
write_command(index, Key, Doc) :-
!,
index(Doc, Key),
atom_chars(Key, KeyChars),
write_doc_chars(KeyChars, Doc).
write_command(Command, _Argument, _Doc) :-
throw(error(unknown_command(Command))).
:- dynamic(index_contents/2).
index_entry(Letter, Key: Sections) :-
index_contents(Key, Sections),
atom_chars(Key, [Letter | _]).
index(Doc, Key) :-
index_new_id(Key, Id),
write(Doc, '<a id="~a" />', [Id]).
index_new_id(Key, Id) :-
nb_getval(current_counters, Counters),
(
retract(index_contents(Key, List))
->
length(List, Count),
SuccCount is Count + 1,
format(atom(Name), '~a_~d', [Key, SuccCount])
;
List = [],
Name = Key
),
make_id(Name, Id),
append(List, [Counters - Id], NewList),
assertz(index(Key, NewList)).
index_use_id(Key, Id) :-
nb_getval(current_counters, Counters),
(
retract(index_contents(Key, List))
->
true
;
List = []
),
append(List, [Counters - Id], NewList),
assertz(index(Key, NewList)).
......@@ -4,6 +4,7 @@
load/1,
load_biocham/1,
new_model/0,
add_item/2,
add_item/3,
item/1,
all_items/2,
......@@ -133,9 +134,10 @@ new_model :-
(
fresh
->
create_item_id(NewModel),
set_current_models([NewModel])
true
;
create_item_id(NewModel),
set_current_models([NewModel]),
assertz(fresh)
).
......@@ -144,7 +146,7 @@ clear_model :-
biocham_command,
doc('clears the current model.'),
single_model(Model),
retractall(item(_, Model, _, _, _)).
retractall(item(_, Model, _, _)).
set_model_name(ModelName) :-
......@@ -160,14 +162,33 @@ not_fresh :-
retractall(fresh).
:- dynamic(item/5).
:- dynamic(item/4).
:- dynamic(key/2).
add_item(Kind, Item) :-
add_item(Kind, [], Item).
add_item(Kind, Key, Item) :-
single_model(Model),
not_fresh,
create_item_id(Id),
assertz(item(Id, Model, Kind, Key, Item)).
(
list(Key)
->
\+ (
member(K, Key),
\+ (
assertz(key(K, Id))
)
)
;
assertz(key(Key, Id))
),
assertz(item(Id, Model, Kind, Item)).
single_model(Model) :-
......@@ -222,7 +243,14 @@ item(Options) :-
;
single_model(Model, ModelId)
),
item(Id, ModelId, Kind, Key, Item).
(
var(Key)
->
true
;
key(Key, Id)
),
item(Id, ModelId, Kind, Item).
all_items(Options, Items) :-
......@@ -254,7 +282,8 @@ list_items(Options) :-
delete_item(Id) :-
retract(item(Id, _Model, _Kind, _Key, _Item)).
retractall(key(_Key, Id)),
retract(item(Id, _Model, _Kind, _Item)).
create_item_id(Id) :-
......
:- use_module(library(plunit)).
:- begin_tests(models).
test('new_model', [true(Rules == [])]) :-
new_model,
add_rule(a => b),
new_model,
all_items([model: current_model, kind: rule], Rules).
:- end_tests(models).
......@@ -5,7 +5,8 @@
op(800, xfx, for),
op(700, xfx, <=),
op(750, xfx, =>),
op(750, xfx, <=>)
op(750, xfx, <=>),
op(700, xfy, =)
]
).
......
......@@ -3,7 +3,8 @@
[
add_rule/1,
list_rules/0,
rule/4
rule/4,
simplify_all_rules/0
]
).
......@@ -12,13 +13,23 @@ add_rule(Rule) :-
type(Rule, reaction),
doc('adds reaction rules to the current set of rules.'),
simplify_rule(Rule, SimplifiedRule),
add_item(rule, SimplifiedRule, SimplifiedRule).
add_item(rule, SimplifiedRule).
list_rules :-
biocham_command,
doc('lists the current set of rules.'),
list_items([model: current_model, kind: rule]).
simplify_all_rules :-
\+ (
item([model: current_model, kind: rule, id: Id, item: Rule]),
\+ (
delete_item(Id),
simplify_rule(Rule, SimplifiedRule),
add_item(rule, SimplifiedRule)
)
).
rule(Item, Kinetics, Reactants, Products, Reversible) :-
(
Item = (Kinetics for Body)
......@@ -101,7 +112,8 @@ solution_to_list(Coefficient * Object, Solution) :-
solution_to_list(Object, [1 * Object]).
list_to_solution([], '_').
list_to_solution([], '_') :-
!.
list_to_solution(List, Solution) :-
reverse(List, [Head | Tail]),
......@@ -153,9 +165,23 @@ simplify_kinetics(Kinetics, KineticsSimplified) :-
).
simplify_solution([], []).
simplify_solution(Solution, SimplifiedSolution) :-
canonical_solution(Solution, CanonicalSolution),
factorize_solution(CanonicalSolution, SimplifiedSolution).
canonical_solution([], []).
canonical_solution(
[Coefficient * Object | Tail], [Coefficient * Canonical | CanonicalTail]
) :-
canonical(Object, Canonical),
canonical_solution(Tail, CanonicalTail).
factorize_solution([], []).
simplify_solution([Coefficient * Object | Tail], SimplifiedSolution) :-
factorize_solution([Coefficient * Object | Tail], SimplifiedSolution) :-
collect_object(Tail, Object, TailCoefficient, Others),
simplify(Coefficient + TailCoefficient, SimplifiedCoefficient),
(
......
......@@ -5,6 +5,6 @@
test('catalyst', [true(Rules == [2 * b <=[ a + c ]=> b])]) :-
new_model,
add_rule(a + b + c <=[ b ]=> a + c),
all_items([kind: rule], Rules).
all_items([model: current_model, kind: rule], Rules).
:- end_tests(rules).
......@@ -20,6 +20,7 @@
** Loading, listing and exporting models
*** Biocham files
- models.pl
- models.plt
** Listing and editing rules and events
*** Rules
- rules.pl
......@@ -29,13 +30,20 @@
** Listing and defining initial states, molecules and locations
*** Initial state
- initial_state.pl
** Listing and declaring parameters, macros and invariants
** Listing and declaring parameters, macros, aliases and invariants
*** Parameters
- parameters.pl
*** Macros
- macros.pl
*** Aliases
- aliases.pl
- aliases.plt
*** Algebraic invariants, conservation laws and P-invariants
- conservation_laws.pl
** Simulations
*** ODE and stochastic simulations
- numerical_simulation.pl
* Index
+ index
* Bibliography
- biocham.bib
......@@ -3,7 +3,9 @@
[
name_variables_and_anonymous/2,
camel_case/2,
equals_to_list/2
equals_to_list/2,
list_to_equals/2,
list/1
]).