ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
protocol.c
Go to the documentation of this file.
1 
11 #include "protocol.h"
12 #include "vmhost.h"
13 #include "semtrex.h"
14 #include "debug.h"
15 
16 extern VMHost *G_vm;
17 
18 void *_o_add_label(char *label,T *def) {
19  T *l = _t_new_root(PROTOCOL_LABEL);
20  _t_new_str(l,ENGLISH_LABEL,label);
21  int path[2] = {1,TREE_PATH_TERMINATOR};
22  _t_insert_at(def,path,l);
23 }
24 
37 T *_o_make_protocol_def(SemTable *sem,Context c,char *label,...) {
38  va_list params;
39  va_start(params,label);
40 
41  Symbol state = PROTOCOL_SEMANTICS;
42  bool in_conv = false;
43  T *p = _t_new_root(PROTOCOL_DEFINITION);
44  T *l = _t_newr(p,PROTOCOL_LABEL);
45  _t_new_str(l,ENGLISH_LABEL,label);
46  T *t = _t_newr(p,PROTOCOL_SEMANTICS);
47  bool done = false;
48  Symbol param;
49  bool pop = false;
50  while(!done) {
51  if (pop) {
52  t = _t_parent(t);
53  p = _t_parent(t);
54  state = _t_symbol(t);
55  if (semeq(_sem_get_symbol_structure(sem,state),INTERACTION)) state = INTERACTION;
56 
57  pop = false;
58  debug(D_PROTOCOL,"popping to state %s with param %s\n",_sem_get_name(sem,state),_sem_get_name(sem,param));
59  }
60  else {
61  param = va_arg(params,Symbol);
62  debug(D_PROTOCOL,"reading %s in state %s\n",_sem_get_name(sem,param),_sem_get_name(sem,state));
63  }
64  if (semeq(state,PROTOCOL_DEFINITION)) {
65  if (semeq(param,INTERACTION)) {
66  state = INTERACTION;
67  }
68  else if (semeq(param,INCLUSION)) {
69  p = t;
70  state = INCLUSION;
71  }
72  else if (semeq(param,NULL_SYMBOL)) {
73  done = true;
74  }
75  else raise_error("expecting ROLE,GOAL,USAGE,INCLUSION,INTERACTION or NULL_SYMBOL got %s",_sem_get_name(sem,param));
76  }
77  if (semeq(state,PROTOCOL_SEMANTICS)) {
78  if (semeq(param,ROLE)) {
79  Symbol role = va_arg(params,Symbol);
80  _t_news(t,ROLE,role);
81  }
82  else if (semeq(param,GOAL)) {
83  Symbol role = va_arg(params,Symbol);
84  _t_news(t,GOAL,role);
85  }
86  else if (semeq(param,USAGE)) {
87  Symbol role = va_arg(params,Symbol);
88  _t_news(t,USAGE,role);
89  }
90  else pop = true;
91  }
92  if (semeq(state,INTERACTION)) {
93  if (semeq(param,INTERACTION)) {
94  Symbol interaction = va_arg(params,Symbol);
95  t = _t_newr(t,interaction);
96  }
97  else if (semeq(param,EXPECT) || semeq(param,INITIATE)) {
98  p = t;
99  state = param;
100  }
101  else pop = true;
102  }
103  if (semeq(state,EXPECT)) {
104  if (semeq(param,EXPECT)) {
105  t = _t_newr(p,EXPECT);
106  Symbol role = va_arg(params,Symbol);
107  _t_news(t,ROLE,role);
108  T *s = _t_newr(t,SOURCE);
109  Symbol source = va_arg(params,Symbol);
110  _t_news(s,ROLE,source);
111  T *pattern = va_arg(params,T*);
112  _t_add(t,pattern);
113  T *action = va_arg(params,T*);
114  _t_add(t,action);
115  }
116  else pop = true;
117  }
118  if (semeq(state,INITIATE)) {
119  if (semeq(param,INITIATE)) {
120  t = _t_newr(p,INITIATE);
121  Symbol role = va_arg(params,Symbol);
122  _t_news(t,ROLE,role);
123  T *s = _t_newr(t,DESTINATION);
124  Symbol source = va_arg(params,Symbol);
125  _t_news(s,ROLE,source);
126  T *action = va_arg(params,T*);
127  _t_add(t,action);
128  }
129  else pop = true;
130  }
131  if (semeq(state,INCLUSION)) {
132  if (semeq(param,INCLUSION)) {
133  t = _t_newr(p,INCLUSION);
134  Symbol pname = va_arg(params,Symbol);
135  _t_news(t,PNAME,pname);
136  }
137  else if (semeq(param,WHICH_SYMBOL)) {
138  T *l = _t_newr(t,RESOLUTION);
139  T *w = _t_newr(l,WHICH_SYMBOL);
140  _t_news(w,USAGE,va_arg(params,Symbol));
141  _t_news(w,ACTUAL_SYMBOL,va_arg(params,Symbol));
142  }
143  else if (semeq(param,WHICH_PROCESS)) {
144  T *l = _t_newr(t,RESOLUTION);
145  T *w = _t_newr(l,WHICH_PROCESS);
146  _t_news(w,GOAL,va_arg(params,Process));
147  _t_news(w,ACTUAL_PROCESS,va_arg(params,Process));
148  }
149  else if (semeq(param,WHICH_RECEPTOR)) {
150  T *l = _t_newr(t,RESOLUTION);
151  T *w = _t_newr(l,WHICH_RECEPTOR);
152  _t_news(w,ROLE,va_arg(params,Symbol));
153  _t_news(w,ACTUAL_RECEPTOR,va_arg(params,Symbol));
154  }
155  else if (semeq(param,WHICH_USAGE)) {
156  T *l = _t_newr(t,LINKAGE);
157  T *w = _t_newr(l,WHICH_USAGE);
158  _t_news(w,USAGE,va_arg(params,Symbol));
159  _t_news(w,USAGE,va_arg(params,Symbol));
160  }
161  else if (semeq(param,WHICH_GOAL)) {
162  T *l = _t_newr(t,LINKAGE);
163  T *w = _t_newr(l,WHICH_GOAL);
164  _t_news(w,GOAL,va_arg(params,Process));
165  _t_news(w,GOAL,va_arg(params,Process));
166  }
167  else if (semeq(param,WHICH_ROLE)) {
168  T *l = _t_newr(t,LINKAGE);
169  T *w = _t_newr(l,WHICH_ROLE);
170  _t_news(w,ROLE,va_arg(params,Symbol));
171  _t_news(w,ROLE,va_arg(params,Symbol));
172  }
173  else pop = true;
174  }
175  }
176  va_end(params);
177  return t;
178 }
179 
180 
181 // hmmm this is kind of like template replace but just looks
182 // for the semantic references, not for SLOTs
183 void _t_replace_sem_refs(T *t, T *sem_map) {
184  if (!t) return;
185 
186  Symbol sym = _t_symbol(t);
187  if (semeq(sym,GOAL)||semeq(sym,ROLE)||semeq(sym,USAGE)) {
188  Symbol valsym = *(Symbol *)_t_surface(t);
189 
190  // scan all the sem_map for semantic refs that match this slot.
191  // @todo convert this to a hashtable based implementation, probably on the treehash of the semantic ref
192  int i,c = _t_children(sem_map);
193  for(i=1;i<=c;i++) {
194  T *m = _t_child(sem_map,i);
195  T *ref = _t_child(m,SemanticMapSemanticRefIdx);
196  if (semeq(sym,_t_symbol(ref)) && semeq(valsym,*(Symbol *)_t_surface(ref))) {
197  T *r;
198  T *replacement_value = _t_child(_t_child(m,SemanticMapReplacementValIdx),1);
199  r = _t_clone(replacement_value);
200  _t_replace_node(t,r);
201  break;
202  }
203  }
204  }
205  else {
206  DO_KIDS(t,_t_replace_sem_refs(_t_child(t,i),sem_map));
207  }
208 }
209 
210 // merges semantic links from the from tree to the into tree only if they don't exist
211 void _o_merge_sem_map(T *from,T *into) {
212  DO_KIDS(from,
213  T *l = _t_child(from,i);
214  T *v = _t_clone(_t_child(l,1));
215  // @todo conceivably this could break for some G_sems, but it shouldn't
216  // it would be better to have a hard-coded or pre-compiled semtrex fragment here
217  // but parsing is easier.
218  T *s = _t_parse(G_sem,0,"(SEMTREX_WALK (SEMTREX_SYMBOL_LITERAL (SEMTREX_SYMBOL:SEMANTIC_LINK) (SEMTREX_VALUE_LITERAL %)))",v);
219  if (!_t_match(s,into)) {
220  _t_add(into,_t_clone(l));
221  }
222  _t_free(s);
223  );
224 }
225 
234 T *_o_bindings2sem_map(T *bindings, T *sem_map,T *defaults) {
235  if (!sem_map)
236  sem_map = _t_new_root(SEMANTIC_MAP);
237  DO_KIDS(bindings,
238  T *res = _t_child(bindings,i);
239  T *w = _t_child(res,ResolutionWhichIdx);
240  T *t = _t_newr(sem_map,SEMANTIC_LINK);
241  _t_add(t,_t_clone(_t_child(w,1)));
242  T *r = _t_newr(t,REPLACEMENT_VALUE);
243  _t_add(r,_t_clone(_t_child(w,2)));
244  );
245  if (defaults) {
246  _o_merge_sem_map(defaults,sem_map);
247  }
248  debug(D_PROTOCOL,"converting bindings %s\n",t2sp(bindings));
249  if (defaults) debug(D_PROTOCOL,"with defaults %s\n",t2sp(defaults));
250  debug(D_PROTOCOL,"to sem map %s\n",t2sp(sem_map));
251  return sem_map;
252 }
253 
262 T * _o_unwrap(SemTable *sem,T *def,T *sem_map) {
263  T *d = _t_clone(def);
264  int i;
265  T *defaults = _t_find(d,PROTOCOL_DEFAULTS);
266  for (i=ProtocolDefOptionalsIdx;i<=_t_children(d);i++) {
267  T *t = _t_child(d,i);
268  if (semeq(_t_symbol(t),INCLUSION)) {
269  Protocol p = *(Protocol *)_t_surface(_t_child(t,InclusionPnameIdx));
270  T *ps = _sem_get_defs(sem,p);
271  T *p_def = _o_unwrap(sem,_t_child(ps,p.id),sem_map); // do the recursive unwrapping
272  int j,c = _t_children(t);
273  T *bindings = NULL;
274  for(j=InclusionPnameIdx+1;j<=c;j++) {
275  T *x = _t_child(t,j); // get the connection or resolution
276  if (semeq(_t_symbol(x),LINKAGE)) {
277  T *w = _t_child(x,ConnectionWhichIdx); // get the which
278  T *t = _t_newr(sem_map,SEMANTIC_LINK);
279  _t_add(t,_t_clone(_t_child(w,1)));
280  T *r = _t_newr(t,REPLACEMENT_VALUE);
281  _t_add(r,_t_clone(_t_child(w,2)));
282  }
283  else if (semeq(_t_symbol(x),RESOLUTION)) {
284  if (!bindings) bindings = _t_new_root(PROTOCOL_BINDINGS);
285  _t_add(bindings,_t_clone(x));
286  }
287  else raise_error("expecting LINKAGE or RESOLUTION");
288  }
289 
290  if (sem_map) {
291  debug(D_PROTOCOL,"filling template %s\n",__t2s(sem,p_def,INDENT));
292  debug(D_PROTOCOL,"with %s\n",__t2s(sem,sem_map,INDENT));
293  _t_replace_sem_refs(p_def,sem_map);
294  debug(D_PROTOCOL,"result %s\n",__t2s(sem,p_def,INDENT));
295  }
296 
297  T *unbound_semantics;
298  if (bindings) {
299  _o_bindings2sem_map(bindings,sem_map,NULL);
300  unbound_semantics = _o_resolve(sem,p_def,sem_map);
301  _t_free(bindings);
302  _t_free(_t_detach_by_idx(p_def,ProtocolDefSemanticsIdx));
303  }
304  else {
305  unbound_semantics = _t_detach_by_idx(p_def,ProtocolDefSemanticsIdx);
306  }
307 
308  // after doing the semantics mapping from the LINKAGEs and RESOLUTIONs
309  // we need to add into the parent semantics and sem_map that weren't resolved
310  // or connected for later binding
311 
312  T *parent_semantics = _t_child(d,ProtocolDefSemanticsIdx);
313  T *x;
314  while(x = _t_detach_by_idx(unbound_semantics,1)) {
315  Symbol sym = _t_symbol(x);
316  c = _t_children(parent_semantics);
317  for (j=1;j<=c;j++) {
318  if (semeq(sym,_t_symbol(_t_child(parent_semantics,j)))) break;
319  }
320  // not found so we can add it
321  if (j>c) {
322  _t_add(parent_semantics,x);
323  debug(D_PROTOCOL,"adding %s to semantics\n",_sem_get_name(sem,sym));
324  }
325  else _t_free(x);
326  }
327  _t_detach_by_ptr(d,t); // remove the INCLUSION specs from the including protocol
328 
329  // handle merging in protocol defaults
330  if (semeq(PROTOCOL_DEFAULTS,_t_symbol(_t_child(p_def,ProtocolDefSemanticsIdx)))) {
331  x = _t_detach_by_idx(p_def,ProtocolDefSemanticsIdx);
332  debug(D_PROTOCOL,"merging defaults: %s",_t2s(sem,x));
333  // if the including protocol has no defaults we can just insert them
334  if (!defaults) {
335  int path[] = {ProtocolDefOptionalsIdx,TREE_PATH_TERMINATOR};
336  _t_insert_at(d,path,x);
337  defaults = x;
338  }
339  else {
340  // otherwise we have to merge in any that don't already exist
341  _o_merge_sem_map(x,defaults);
342  _t_free(x);
343  }
344  }
345 
346  // add in the unwrapped interactions
347  while(x = _t_detach_by_idx(p_def,ProtocolDefSemanticsIdx)) {
348  _t_add(d,x);
349  }
350  _t_free(unbound_semantics);
351  _t_free(p_def);
352  }
353  }
354  debug(D_PROTOCOL,"unwrapped to: %s\n",__t2s(sem,d,INDENT));
355 
356  return d;
357 }
358 
359 
372 T * _o_resolve(SemTable *sem,T *def, T *sem_map){
373 
374  // calculate the list of still unbound semantics
375  T *semantics = _t_clone(_t_child(def,ProtocolDefSemanticsIdx));
376 
377  if (sem_map) {
378  _t_fill_template(def,sem_map);
379  int i,c = _t_children(sem_map);
380  for(i=1;i<=c;i++) {
381  T *x = _t_child(_t_child(sem_map,i),SemanticMapSemanticRefIdx);
382  Symbol symx = _t_symbol(x);
383  Symbol symxs = *(Symbol *) _t_surface(x);
384  int j,b = _t_children(semantics);
385  // search the semantics for matching item and remove it.
386  for(j=1;j<=b;j++) {
387  T *y = _t_child(semantics,j);
388  if (semeq(symx,_t_symbol(y)) && semeq(symxs,*(Symbol *) _t_surface(y))) {
389  _t_free(_t_detach_by_idx(semantics,j));
390  break;
391  }
392  }
393  }
394  }
395 
396  return semantics;
397 }
398 
409 void _o_express_role(Receptor *r,Protocol protocol,Symbol role,Aspect aspect,T *bindings) {
410  T *p = _sem_get_def(r->sem,protocol);
411  if (!p) raise_error("protocol %s not found",_sem_get_name(r->sem,protocol));
412  T *sem_map = _t_new_root(SEMANTIC_MAP);
413  p = _o_unwrap(r->sem,p,sem_map); // creates a cloned, uwrapped protocol def.
414  if (bindings) {
415  _o_bindings2sem_map(bindings,sem_map,_t_find(p,PROTOCOL_DEFAULTS));
416  }
417  T *unbound = _o_resolve(r->sem,p,sem_map);
418  debug(D_PROTOCOL,"express %s yelids unbound: %s\n",_sem_get_name(r->sem,role),_t2s(r->sem,unbound));
419  debug(D_PROTOCOL,"express %s yelids sem_map: %s\n",_sem_get_name(r->sem,role),_t2s(r->sem,sem_map));
420  if (!_t_children(sem_map)) {
421  _t_free(sem_map);
422  sem_map = NULL;
423  }
424  //@todo convert this search to be repeat Semtex matching on INTERACTION structure...
425  T *t;
426  int i,c=_t_children(p);
427  for(i=1;i<=c;i++) {
428  t = _t_child(p,i);
429  Symbol interaction = _t_symbol(t);
430  if (semeq(_sem_get_symbol_structure(r->sem,interaction),INTERACTION)) {
431  int j;
432  int b = _t_children(t);
433  for(j=1;j<=b;j++) {
434  T *x = _t_child(t,j);
435  if (semeq(_t_symbol(x),EXPECT)) {
436  T *rl = _t_child(x,ExpectRoleIdx);
437  if (semeq(*(Symbol *)_t_surface(rl),role)) {
438  T *pattern = _t_clone(_t_child(x,ExpectPatternIdx));
439  // @todo check pattern for unbound USAGEs
440 
441  T *a = _t_clone(_t_child(x,ExpectActionIdx));
442  if (!bindings && semeq(_t_symbol(a),GOAL)) {
443  raise_error("binding missing for GOAL:%s in %s",_sem_get_name(r->sem,*(SemanticID *)_t_surface(a)),_t2s(r->sem,x));
444  }
445  T *sm = sem_map ? _t_clone(sem_map) : NULL;
446  T *params = _t_child(x,ExpectParamsIdx);
447  if (params) params = _t_clone(params);
448  T *e = __r_build_expectation(interaction,pattern,a,params,0,sm,NULL);
449  debug(D_PROTOCOL,"express %s adds expectation: %s\n",_sem_get_name(r->sem,role),_t2s(r->sem,e));
450  __r_add_expectation(r,aspect,e);
451  }
452  }
453  }
454  }
455  }
456  _t_free(p);
457  if (unbound) _t_free(unbound);
458  if (sem_map) _t_free(sem_map);
459 }
460 
473 T * __o_initiate(Receptor *r,SemanticID protocol,SemanticID interaction,T *bindings,T **sem_mapP) {
474  T *p = _sem_get_def(r->sem,protocol);
475  if (!p) raise_error("protocol %s not found",_sem_get_name(r->sem,protocol));
476  T *sem_map = _t_new_root(SEMANTIC_MAP);
477  p = _o_unwrap(r->sem,p,sem_map); // creates a cloned, uwrapped protocol def.
478  if (bindings) {
479  _o_bindings2sem_map(bindings,sem_map,_t_find(p,PROTOCOL_DEFAULTS));
480  }
481  T *ia = _t_find(p,interaction);
482  if (!ia) raise_error("interaction '%s' not found in protocol definition",_sem_get_name(r->sem,interaction));
483  T *initiate = _t_find(ia,INITIATE);
484  if (!initiate) raise_error("no INITIATE found in %s interaction",_sem_get_name(r->sem,interaction));
485  //@todo somehow check that we've expressed the role in INITIATE
486 
487  T *action = _t_child(initiate,InitiateActionIdx);
488  Process proc = *(Process*) _t_surface(action);
489  T *params = _t_new_root(PARAMS); //@todo fix this, would should probably get params from the INITIATE?
490  T *rt = _p_make_run_tree(r->sem,proc,params,sem_map);
491  _t_free(params);
492  _t_free(p);
493 
494  *sem_mapP = sem_map;
495  return rt;
496 }
497 
506 void _o_initiate(Receptor *r,SemanticID protocol,SemanticID interaction,T *bindings) {
507  T *sem_map;
508  T *rt = __o_initiate(r,protocol,interaction,bindings,&sem_map);
509  __p_addrt2q(r->q,rt,sem_map);
510 }
511 
512 
T * _t_new_root(Symbol symbol)
Definition: tree.c:160
char * _sem_get_name(SemTable *sem, SemanticID s)
Definition: semtable.c:85
Definition: ceptr_types.h:114
T * _o_bindings2sem_map(T *bindings, T *sem_map, T *defaults)
Definition: protocol.c:234
T * _t_detach_by_idx(T *t, int i)
Definition: tree.c:278
Semantic tree regular expression header file.
T * _t_clone(T *t)
Definition: tree.c:589
Symbol _t_symbol(T *t)
Definition: tree.c:1228
T * _t_child(T *t, int i)
Definition: tree.c:1251
protocol helpers header file
vmhost implementation header file
void _t_insert_at(T *t, int *path, T *i)
Definition: tree.c:438
Q * q
process queue
Definition: ceptr_types.h:250
int _t_match(T *semtrex, T *t)
Definition: semtrex.c:809
void * _t_surface(T *t)
Definition: tree.c:1215
T * _o_unwrap(SemTable *sem, T *def, T *sem_map)
Definition: protocol.c:262
void _t_replace_node(T *t, T *r)
Definition: tree.c:391
SState * state(StateType type, int *statesP, int level)
Definition: semtrex.c:103
T * _t_parent(T *t)
Definition: tree.c:1262
void _o_initiate(Receptor *r, SemanticID protocol, SemanticID interaction, T *bindings)
Definition: protocol.c:506
Qe * __p_addrt2q(Q *q, T *run_tree, T *sem_map)
Definition: process.c:2068
Definition: vmhost.h:40
SemTable * sem
pointer back to the genotype table for this receptor's vmhost instance
Definition: ceptr_types.h:242
void _o_express_role(Receptor *r, Protocol protocol, Symbol role, Aspect aspect, T *bindings)
Definition: protocol.c:409
char * __t2s(SemTable *sem, T *t, int indent)
Definition: def.c:518
T * _t_parse(SemTable *sem, T *parent, char *s,...)
Definition: tree.c:919
void _t_add(T *t, T *c)
Definition: tree.c:261
int _t_children(T *t)
Definition: tree.c:1205
T * _o_make_protocol_def(SemTable *sem, Context c, char *label,...)
Definition: protocol.c:37
void _t_detach_by_ptr(T *t, T *c)
Definition: tree.c:291
void _t_free(T *t)
Definition: tree.c:526
T * __o_initiate(Receptor *r, SemanticID protocol, SemanticID interaction, T *bindings, T **sem_mapP)
Definition: protocol.c:473
T * _p_make_run_tree(SemTable *sem, Process p, T *params, T *sem_map)
Definition: process.c:1974
T * _o_resolve(SemTable *sem, T *def, T *sem_map)
Definition: protocol.c:372