Click here to see the empty trace obtained by running the empty model.
{
"dict":{
"agent":{"id":0,"type":1},
"binding_type":{"type":0,"site":1},
"quark":{"agent":0,"site":1},
"test":["Is_here","Has_Internal","Is_Free","Is_Bound","Has_Binding_type","Is_Bound_to"],
"actions":["Create","Mod_internal","Bind","Bind_to","Free","Remove"],
"binding_state":["ANY","FREE","BOUND","BOUND_TYPE","BOUND_to"],
"event":{"tests":0,"actions":1,"side_effect_src":2,"side_effect_dst":3,"connectivity_tests":4},
"simulation_info":{"id":0,"time":1,"event":2,"profiling":3},
"step":["Subs","Rule","Pert","Init","Obs","Dummy"]
},
"model":{
"filenames":["","model.ka"],
"update":{
"signatures":[],
"single_agents":[],
"elementaries":[],
"dag":[{"content":null,"roots":null,"deps":[],"sons":[]}],
"id_by_type":[],
"max_obs":1
},
"tokens":[],
"algs":[],
"observables":["[T]"],
"ast_rules":[],
"elementary_rules":[],
"contact_map":[],
"interventions":[],
"dependencies_in_time":[],
"dependencies_in_event":[],
"algs_reverse_dependencies":[],
"tokens_reverse_dependencies":[]
},
"trace":[]
}
It is nearly valid JSON. It is not because the order of the
fields in the top object (dict
,model
and trace
) is fixed and that's forbidden by the JSON
specification.
Also, as described later, the "steps" in the trace are
represented in a compact format (using arrays for records and
numbers for enumerate types) instead of the one you would normally
expect (using respectively objects and strings). The purpose of
the dict
field is exactly to do the
correspondance.
{"x":foo,"y":bar}
, it will be represented it
as [foo,bar]
and there will be in the "dict" the
entry "point":{"x":0,"y":1}
to specify that the
field "x" is the first element and "y" the second.Cat
, Dog
or Licorn
. Instead of writing "Dog"
,
we use 1
and put in the
dict "pet":["Cat","Dog","Licorn"]
once for
all.In order to use KaStor, you need to fill:
signatures
field of the update
field
of model
,ast_rules
field of model
,trace
The field signatures
is also a kind of
dictionary. It gives the name of agent types, sites and
internal states of the model. In the rest of the file,
references to agent type, site and internal state are made by
their "id" in this dictionary
Let's pretend an example is enough to specify its format. The Kappa signature
%agent: C(c1 c2 c3 c4)
%agent: O(o1 o2)
%agent: H(h{p d t})
is represented by
"signatures":[
{"name":"C","decl":[{"name":"c1","decl":[[],null,null]},{"name":"c2","decl":[[],null,null]},{"name":"c3","decl":[[],null,null]},{"name":"c4","decl":[[],null,null]}]},
{"name":"O","decl":[{"name":"o1","decl":[[],null,null]},{"name":"o2","decl":[[],null,null]}]},
{"name":"H","decl":[{"name":"h","decl":[[{"name":"p","decl":null},{"name":"d","decl":null},{"name":"t","decl":null}],null,null]}]}
]
The 2 extra null
arguments of
the decl
of a site (after the declaration of the
internal states) have to be present but they don't matter
here.
The field ast_rules
is the table of the rules of
the model. Each element is a pair (rule name, rule
content). The content does not matter here as soon as a name
is provided so the "content" of the empty rule can be duplicated
everywhere as the fake content of the rule. Again, in the
"steps" of the trace rules are identified by their id in this
table.
{"mixture":[],"created":[],"delta_tokens":[],"rate":{"val":0,"loc":{"file":0,"bline":-1,"bchr":-1,"echr":-1}},"unary_rate":null,"editStyle":true}
As an example, If your model has 2 rules "foo" and "bar", your trace file will contain:
"ast_rules": [
["foo",{"mixture":[],"created":[],"delta_tokens":[],"rate":{"val":0,"loc":{"file":0,"bline":-1,"bchr":-1,"echr":-1}},"unary_rate":null,"editStyle":true}],
["bar",{"mixture":[],"created":[],"delta_tokens":[],"rate":{"val":0,"loc":{"file":0,"bline":-1,"bchr":-1,"echr":-1}},"unary_rate":null,"editStyle":true}]
]
Given that we use the compact representation described above,here is the top down description (written in OCaml type declaration syntax)
type trace = step list
type step =
| Subs of int * int
| Rule of int * event * simulation_info
| Pert of string * event * simulation_info
| Init of action list
| Obs of string * test list list * simulation_info
| Dummy of string
Subs
and Dummy
Rule
.model.ast_rule
table) of the rule.Pert
Init
Obs
type simulation_info = {
story_id: int ;
story_time: float ;
story_event: int ;
profiling_info: null ;
}
type event = {
tests : test list list;
(** The tests written in the rule (connected component by connected component) *)
actions : action list; (** The modifications written in the rule *)
side_effects_src : (site * binding_state) list
(** the site of the agents mentioned in the rule where there is a side
effects *);
side_effects_dst : site list
(** the site of agents not mentionned in the rule that have been freed
by side effect *);
connectivity_tests : test list;
(** witness that patterns where connected (Only in unary instances of molecular rule. An empty list in any other case) *)
}
type action =
| Create of agent * (int * int option) list
| Mod_internal of site * int (** internal state id *)
| Bind of site * site
| Bind_to of site * site
| Free of site
| Remove of agent
When an agent is Create
d, you must introduce all
its sites as either Free
or Bind_to
as
well as all internal states (when they exists)
using Mod_internal
. Beware
of Create
ing both extremities of a created edge
before putting the Bind_to
.
When the action is to link 2 sites already present in the
soup, Bind
is used and
not Bind_to
.
The second argument of the constructor Created
is a part of the technical debt of the Kappa source code. You
have to give the list of the sites and duplicate the internal
state in which the site are introduced (when they is one). Yes,
this is as dumb as
writing [[0,null],[1,null],[2,null]]
each time you
introduce an agent with 3 sites (and no internal state)... Any
question must be asked to Jérôme Feret :-)
type test =
| Is_Here of agent
| Has_Internal of site * int (** internal state id *)
| Is_Free of site
| Is_Bound of site
| Has_Binding_type of site * binding_type
| Is_Bound_to of site * site
When you test some site of an agent, you must have tested before Is_Here
of that agent...
type binding_state =
| ANY
| FREE
| BOUND
| BOUND_TYPE of binding_type
| BOUND_to of site
type site = agent * int (** site id *)
type agent = int (** agent id *) * int (** agent type id *)
type binding_type = int (** agent type id *) * int (** site id *)