Browse Source

MP2 updates as for April 7, 2015

mikau2 10 years ago
commit
eb5c9ad6a9
18 changed files with 3356 additions and 0 deletions
  1. 669 0
      MP2-generator.rig
  2. 948 0
      MP2-parser.rig
  3. BIN
      MP2-syntax.pdf
  4. 43 0
      Summer2015.mp
  5. 314 0
      Swarm2.mp
  6. 13 0
      etude14.mp
  7. 22 0
      etude15.mp
  8. 13 0
      etude16.mp
  9. 37 0
      etude17.json
  10. 19 0
      etude17.mp
  11. 14 0
      etude18.mp
  12. 11 0
      etude19.mp
  13. 10 0
      etude20.json
  14. 14 0
      etude20.mp
  15. 24 0
      lexer.mp
  16. 947 0
      mp2.h
  17. 244 0
      mp2_print_etc.h
  18. 14 0
      rall

+ 669 - 0
MP2-generator.rig

@@ -0,0 +1,669 @@
+-- MP_generator.rig   Phoenix -> C++ code generator  
+-- V 2.0 
+-- Mikhail Auguston, 03/05/15
+-- last modified 04/05/15
+-- use: MP_generator intermediate_file 
+--
+-----------------------------------
+#AG
+-- Globals:
+--	$roots			-- retain the original MP code,
+--	$composites		-- these are used for comment generation
+--  $atoms			-- for event name generation
+--  $new_root_table
+--  $new_composites
+--  $composite_order -- for harvest() calls ordering
+
+--  $class_counter
+--  $generated_containers: <* work_name: T *>
+----------------------------------------------
+
+  $Parm:= #PARM(T);
+  $input_file:= #IMPLODE( $Parm [1]);
+  LOAD $model $input_file;
+	$roots:=			$model.roots;
+	$composites:=		$model.composites;
+	$atoms:=			$model.atomic_events;
+	$new_root_table:=	$model.new_root_table;
+	$new_composites:=	$model.new_composites;
+	$composite_order:=	$model.composite_order;
+	$coordinate_ops:=	$model.coordinate_ops;
+	$share_all_ops:=	$model.share_all_ops;
+		
+  OPEN GEN #IMPLODE( $model.schema '.cpp' ); -- for C++ code
+  OPEN MSG ' ';								 --for error messages
+  --MSG<< 'Phoenix/C++ generator v.2.0 input from '  $input_file;
+  
+  GEN<< '/* Monterey Phoenix-> C++ generator, v.2.0, March 2015';
+  GEN<< '   Mikhail Auguston, NPS, CS Dept, Monterey, CA, USA';GEN<<;
+  GEN<< '   traces derived for scope' $model.scope;
+  GEN<< '----------------------------------------------------';
+  GEN<< 'SCHEMA' $model.schema;
+  -- print comments with the original MP code
+  #print_rule_list(root $roots);
+  #print_rule_list(composite $composites);
+     
+  GEN<<;
+  GEN<< '*****************************************************************'; 
+  GEN<< '***' generated constants are visible in the 'mp2_print_etc.h';
+  GEN<< '*****************************************************************/';
+  GEN<< '#include "mp2.h" // the permanent part';GEN<<;
+     
+	#generate_event_names();
+	#generate_event_strings();
+
+	GEN<< '#include "mp2_print_etc.h" // print methods';
+	GEN<< '//***************************';
+	GEN<< '//==== generated classes ====';
+	GEN<< '//***************************';
+	GEN<<;
+	
+	$class_counter:= 0;
+	#generate_composite_producers($new_composites);
+	#generate_composite_producers($new_root_table);
+	#generate_event_class($new_composites);
+	#generate_event_class($new_root_table);
+	#generate_coordination_class($coordinate_ops);
+	#generate_share_all_class($share_all_ops);
+	#generate_schema_class($model.elt_list);
+    
+	GEN<< '//******************************************';
+	GEN<< '//'	main;
+	GEN<< '//******************************************';
+	GEN<< 'int main(){';
+	GEN<< '   gen_start = clock();';
+	GEN<<  @ '   JSON.open("' $model.schema '.json");';
+	GEN<<    '   cout<< "generating traces for scope' $model.scope '"<<endl;';
+	GEN<< '//----------------------------';
+	#generate_harvest_calls($composite_order);
+	#harvest_roots($new_root_table);
+	#harvest_main_schema();
+
+	-- generate statistics show
+	GEN<< '//----------------------------';
+	GEN<< '   show_statistics();';
+	GEN<< 'return 0;';
+	GEN<< '} // end main()';
+##
+--------------------------------------------------
+--  print subroutines ----------------------------
+--------------------------------------------------
+#print_rule_list
+-- Global: $buffer_len  -- should be <= 80
+	( root /$type:= ROOT/ ! $x)
+	<* $rule_name: 
+			/GEN<<  $type @ $rule_name ': ';
+			 $buffer_len:= #LEN($rule_name) + 10/
+			<. pattern_list: #print_element .>
+			/ GEN<] ';'/
+	*>
+##
+
+#print_element
+	<.	type: plain,
+		name: $event_name 
+			/IF LAST #print_rule_list $buffer_len + #LEN($event_name) > 68 ->
+				GEN<< '       '; 
+				LAST #print_rule_list $buffer_len:= 10
+			 FI;
+			 GEN<] $event_name; 
+			 LAST #print_rule_list $buffer_len +:= #LEN($event_name) +1/
+	.>;;
+
+	<.	type:	sequence,
+		body:	(. (*   #print_element  *) .)
+	.>;;
+	
+	<.	type:	alternative,
+		body:	/GEN<] '('/
+			(. (* /GEN<] $bar; $bar:= '|'/  #print_element  *) .)
+			/GEN<] ')'/
+	.>;;
+
+	<.	type:	iterator,
+		body:	/GEN<] '(*'/  #print_element /GEN<] '*)'/
+	.>;;
+
+	<.	type:	iterator_plus,
+		body: /GEN<] '(+'/  #print_element /GEN<] '+)'/
+	.>;;
+	
+	<.	type:		set,
+		body: /GEN<] '{'/
+			(. (* /GEN<] $bar; $bar:= ','/  #print_element  *) .)
+			/GEN<] '}'/
+	.>;;
+
+	<.	type:		set_iterator,
+		body: /GEN<] '{*'/ #print_element /GEN<] '*}'/
+	.>;;
+
+	<.	type:		set_iterator_plus,
+		body: /GEN<] '{+'/ #print_element /GEN<] '+}'/
+	.>;;
+	
+	<.	type:		optional,
+		body: /GEN<] '['/  #print_element /GEN<] ']'/
+	.>;;
+		
+	<. type: empty .> ;; -- EMPTY
+
+	$x /GEN<< '**' $x.type print not implemented yet '**'/
+##
+
+------------------------------------------------------------------
+-------- generate event names enum and strings
+------------------------------------------------------------------
+
+-- GenericContainer is used for all Alt (OR), Seq (AND), Set producers
+#generate_event_names
+	/GEN<< 'enum Event_name {Dummy_event, GenericContainer';
+	 GEN<< '       // atomic events'; 
+	 #print_event_name(LAST #AG $atoms);
+	 GEN<< '       // composite events'; 
+	 #print_event_name(LAST #AG $composites);
+	 GEN<< '       // coordination operations'; 
+	 #print_event_name(LAST #AG $coordinate_ops);
+	 GEN<< '       // share all operations'; 
+	 #print_event_name(LAST #AG $share_all_ops);	 	 
+	 GEN<< '       // ROOT events';
+	 #print_event_name(LAST #AG $roots);
+	 GEN<< '       // main schema event'; 
+	 GEN<< @ '    , Event_' LAST #AG $model.schema;
+	 GEN<] ' };'; GEN<<;/ 
+##
+
+#print_event_name
+	<* $event_name: $x 
+		/GEN<< @ '    , Event_' $event_name /
+	*>
+##
+
+#generate_event_strings
+	/GEN<< 'string event_name_string[] = {"Dummy", "GenericContainer"';
+	 #print_event_string(LAST #AG $atoms);
+	 #print_event_string(LAST #AG $composites);
+	 #print_event_string(LAST #AG $coordinate_ops);
+	 #print_event_string(LAST #AG $share_all_ops);
+	 #print_event_string(LAST #AG $roots);
+	 GEN<< @ '     , "' LAST #AG $model.schema '"';
+	 GEN<] ' };'; GEN<<;/ 
+##
+
+#print_event_string
+	<* $event_name: $x 
+		/GEN<< @ '     , "' $event_name '"' /
+	*>
+##
+
+--********************************************************************
+--------------------------- EVENT CLASSES ----------------------------
+--********************************************************************
+#generate_composite_producers
+	<* $event_name:	<. pattern_list:	#generate_container,
+					   [build_block:	$comp_op_list
+							-- here comes composition op class generator <<<<<<<<<< 
+						]
+					.>
+	*>		
+##
+
+#generate_container
+	<. type: ( plain ! composite ! empty ) .> ;;
+	
+	-- for event grammar patterns
+	<. name: $work_name
+				/IF LAST#AG $generated_containers.$work_name -> 
+					RETURN T 
+				 FI/, -- to prevent duplication
+					
+	   type: (	sequence	/$base:= AND_node_producer_container/ ! 
+				alternative /$base:= OR_node_producer_container/  ! 
+				set			/$base:= SET_node_producer_container/ ),
+				
+	   body: (. (* #generate_container *) .), -- for nested ALT, SEQ, SET
+
+	   body: 
+			/GEN<< '//----' #class_counter() '----';
+			 GEN<< class $work_name ': public' $base '{';
+			 GEN<< 'public:' '//' constructor;
+			 GEN<< '   ' $work_name '():' $base '(GenericContainer){';
+			 GEN<< '      element =	new Event_producer_ref[ element_count =' 
+					#LEN($.body) + #LEN(LAST #generate_composite_producers $comp_op_list) 
+					'];'; 
+			 $element_count:= 0 /
+			(. (* /GEN<< '      element[' $element_count ']= '/
+					#generate_element 
+				  /GEN<] ';';
+				   $element_count +:= 1 /
+				*) .)
+	.> 
+				
+		/GEN<< '    }';
+		 GEN<< '};//' end class $work_name;
+		 GEN<<;
+		 LAST#AG $generated_containers ++:= <. $work_name: T .> / 
+##
+
+#generate_element
+
+	<.	type: plain,
+		name: $Id    .>
+	/GEN<] @ 'new Atomic_producer(Event_' $Id ')'/;;
+
+	<. type: composite,
+	   name: $Id		.>
+	/GEN<] @ 'new Composite_secondary_producer(Event_' $Id ')'/;;
+	
+	<. type: (sequence ! alternative ! set),
+	   name: $work_name		.>
+	/GEN<] new $work_name/;;
+	
+	<.	type: empty .> 
+	/GEN<] '&Dummy'/;;
+	
+	-- here come composition op elements <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+	
+	$x /PRINT (. '***' Unrecognized element $x .)/
+	
+##
+
+#generate_event_class
+
+	<* $event_name:  
+		<. rule_type: ( composite /$target_event:= Composite_event_instance_node/ ! 
+						ROOT	  /$target_event:= ROOT_node/ ),
+							
+		   work_name:	$work_name
+					/GEN<< '//----' #class_counter() '----';
+					GEN<< class $work_name ': public Composite_producer {';
+					GEN<< 'public:' '//' constructor;
+					GEN<< '   ' $work_name @ '(): Composite_producer(Event_' $event_name '){';
+					GEN<< '      target_event =' $target_event ';';
+					GEN<< '      element =	new Event_producer_ref[ element_count =' 
+					1 + #LEN($.$event_name.build_block) '];'; 
+					$element_count:= 0 /,
+	 
+		   pattern_list: -- on the top level in composite always just single pattern
+							/GEN<< '      element[' $element_count ']= '/
+							#generate_element 
+							/GEN<] ';';
+							 $element_count +:= 1 /,  
+
+		   [build_block:	$comp_op_list ]
+		.>
+		/GEN<< '    }';
+		GEN<< '};//' end class $work_name;
+		GEN<< /
+	 *> 
+##
+
+#generate_coordination_class
+-- global:
+-- $nesting_depth for avoiding redundant create_matrices() calls
+-------------------------
+	<* $work_name: 
+		/GEN<< '//----' #class_counter() '----';
+		GEN<< class @ $work_name '_ob: public Coordinate {';
+		GEN<< 'public:' '//' constructor;
+		GEN<< '   ' @ $work_name '_ob(int n): Coordinate(n){ }';
+				GEN<<;
+
+
+		GEN<< '    Traversal_result traverse(){';
+		GEN<< ' try{';
+		$nesting_depth:= 0/
+		
+		#generate_operation
+		
+		/GEN<< ' }';
+		 GEN<< ' catch(Traversal_result t){';
+		 GEN<< '   delete_matrices();';
+		 GEN<< '   return failed;';
+		 GEN<< ' }';
+		 GEN<< ' delete_matrices();';
+		 GEN<< ' return success_and_completed;';
+		 GEN<< '    } // end traverse()';
+		 GEN<< '}; // end' @ $work_name '_ob class';
+		 GEN<</
+	*>
+##
+
+#generate_share_all_class
+	<* $work_name: 
+		/GEN<< '//----' #class_counter() '----';
+		GEN<< class @ $work_name '_ob: public Coordinate {';
+		GEN<< 'public:' '//' constructor;
+		GEN<< '   ' @ $work_name '_ob(int n): Coordinate(n){type = ShareAll_op;}';
+		GEN<<;
+		GEN<< '    Traversal_result traverse(){';
+		GEN<< ' try{';/
+		
+		#generate_operation
+		
+		/GEN<< ' }';
+		 GEN<< ' catch(Traversal_result t){';
+		 GEN<< '   delete_matrices();';
+		 GEN<< '   return failed;';
+		 GEN<< ' }';
+		 GEN<< ' delete_matrices();';
+		 GEN<< ' return success_and_completed;';
+		 GEN<< '    } // end traverse()';
+		 GEN<< '}; // end' @ $work_name '_ob class';
+		 GEN<</
+	*>
+##
+
+#generate_operation
+	/LAST #generate_coordination_class $nesting_depth +:= 1/
+	<.	synchronization: $synchronization,
+
+		operation:	 COORDINATE 
+					/GEN<< '  //' $synchronization COORDINATE operation;
+					 GEN<< '  create_matrices();'/,
+							 
+		source_list: <*  $variable: 
+							/GEN<<;
+							GEN<< '  int' $variable '; // variable';
+							GEN<< @ '  vector<int> ' $variable 
+									'_list; // list of coordinated events' / 
+								<. from: 
+									( <. comp: $source .>  
+										/$source_name:= #IMPLODE($source '_source');
+										IF NOT $source_defined.$source ->
+											GEN<< '  int ' $source_name 
+												'; // source of coordination';
+											$source_defined++:= <. $source: T .>
+										FI;
+										GEN<<;
+										GEN<< '   // find source event' $source;
+										GEN<< '   for(int i = 0; i < Stack.size(); i++){';
+										GEN<< @'     if( Stack[i]->name == Event_' $source '){';
+										GEN<< '        ' $source_name '= i; break; }';
+										GEN<< '   }'/							!
+									  <. var: $v .>	
+										/$source_name:= $v/					
+									)
+									/$source_list!.:= (. $variable  $source_name .);
+									 $source_tree++:= <. $variable: $source_name .>/
+								.>
+					*>,
+					
+					-- second pass
+		source_list: /GEN<<;
+					  GEN<< '  // create lists of coordinated events';
+					  GEN<< '  for(int i = 0; i < len; i++){'/
+					  
+					 <*  $variable:
+							/GEN<< '    if(in_matrix[i * len + ' $source_tree.$variable ']){';
+							 GEN<< @'      if(';
+							 $or_op:= ' '/
+							<. selection_pattern: (. (*  
+										/GEN<] @ $or_op '(Stack[i]->name == Event_' /
+												$event_name
+										/GEN<] @ $event_name ')';
+										 $or_op:= '||'/
+													  *) .) 
+							.>
+							/GEN<] @ ' ){'; 
+							 GEN<<  '	   //' make sure this is fresh event not yet shared;
+							 GEN<<  '       int found = 0;';
+							 GEN<< @'       for(vector<int>::  iterator s = ' 
+									$variable  '_list.begin(); s != ' $variable '_list.end(); s++){';
+							 GEN<<  '         if((found = eq_matrix[i * len + *s])) break;';
+							 GEN<<  '       }';
+							 GEN<< @'       if(!found) ' $variable '_list.push_back(i);';
+							 GEN<<  '      }';
+							 GEN<< '     }'/		
+					 *>					 
+					 
+					 /GEN<< '  }';
+					  IF #LEN($source_list) > 1 ->
+						GEN<< '  //' check that selected lists are of the same length;
+						GEN<< @ '  if(';
+						$first_arg:= #IMPLODE($source_list[1][1] '_list.size() != ');
+						$i:= 2;
+						$or_op:= ' ';
+						LOOP
+							IF $i > #LEN($source_list) -> BREAK FI;
+							GEN<] $or_op @ $first_arg $source_list[$i][1] '_list.size() ';
+							$i +:= 1;
+							$or_op:= '||';
+						END;
+						GEN<] ') throw failed;'
+					  FI/,
+					  
+		synchronization:	( Synchronous
+								/GEN<<;
+								 GEN<< '  //' for syncronized COORDINATE sort the list 
+											and check for total order;
+								 FORALL $var IN $source_list DO
+									GEN<< @ '  sort_and_check_coordinated_events(' $var[1] '_list);'
+								 OD /		!
+							  $a ),
+							  
+		body:	/GEN<<;
+				 GEN<< '  //' do the COORDINATE;
+				 GEN<< '  for(int i = 0; i <' #IMPLODE($source_list[1][1] '_list.size()') '; i++){';
+				 FORALL $var IN $source_list DO
+					GEN<< @ '    ' $var[1] '= ' $var[1] '_list[i];'
+				 OD/
+				 (. (+ 
+					 (	<.  operation:'ADD',
+							relation_list:	(. (+ 
+								<.first:	$var1, 
+								  second:	$var2, 
+								  relation: ( PRECEDES
+											  /GEN<< @'    Follows.insert(pair<int, int>(' $var2 ',' $var1 '));'/ !
+											  FOLLOWS
+											  /GEN<< @'    Follows.insert(pair<int, int>(' $var1 ',' $var2 '));'/ !
+											  'IN'
+											  /GEN<< @'    Inside.insert(pair<int, int>(' $var1 ',' $var2 '));'/ !
+											  CONTAINS
+											  /GEN<< @'    Inside.insert(pair<int, int>(' $var2 ',' $var1 '));'/ 
+											)
+								.> 
+											    +) .)
+						.>			!
+						
+						#generate_operation !
+						
+						<.  operation: $op .> 
+							/MSG<< '*****' operation $op is not yet implemented/ 
+					 )
+				    +) 
+				.)
+				 /GEN<< '  }';
+				  IF LAST #generate_coordination_class $nesting_depth < 2 ->
+					GEN<< '  create_matrices(); //' to check for axiom violation;
+					GEN<< '  //print_matrices(); //<<<<<<<<<<<<'
+				  FI;
+				  GEN<< '  //' end of COORDINATE;
+				  LAST #generate_coordination_class $nesting_depth +:= -1/
+	.>;;
+	
+----------------------------------------------------------------------------------	
+	<.	operation:	 SHARE_ALL 
+					/GEN<<;
+					 GEN<< '  //' SHARE ALL operation;
+					 GEN<< '  create_matrices();'/,
+					 
+		shared_events: $shared_events,
+			
+		host_list: (. (*  (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ ! 
+							  <. var: $host_name .> /$source_name:= $host_name/)
+								-- single host
+							/$hosts ++:= <. $host_name: T .>;
+							 GEN<<;
+							 IF $source_name <> $host_name ->
+								GEN<<  '  int' $source_name ';// shareholder';
+								GEN<<  '  // find host event' $host_name;
+								GEN<<  '  for(int i = 0; i < Stack.size(); i++){';
+								GEN<< @'   if( Stack[i]->name == Event_' $host_name '){';
+								GEN<<  '     ' $source_name '= i; break; } }';
+							 FI;
+							 GEN<<  '   // lists of shared events for ' $host_name;
+							 FORALL $e IN $shared_events DO
+							   GEN<< @'  vector<int> ' $host_name '_' $e '_list;'
+							 OD;/
+						  .)
+						*)
+					.),
+					
+		host_list: /GEN<<;
+					GEN<< '  //' create lists of shared events;
+					GEN<< '  for(int i = 0; i < len; i++){'/
+					
+					(. (*  (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ ! 
+							   <. var: $host_name .> /$source_name:= $host_name/)
+								-- single host
+							/GEN<<  '   if(in_matrix[i * len +'  $source_name ']){';
+							 FORALL $e IN $shared_events DO
+								GEN<< @'     if( Stack[i]->name == Event_' $e ' ){';
+								GEN<<  '	   //' make sure this is fresh event not yet shared;
+								GEN<<  '       int found = 0;';
+								GEN<<  '       for(vector<int>::  iterator s = ' 
+									@$host_name '_' $e '_list.begin();';
+								GEN<< @ '          s != ' $host_name '_' $e 
+									'_list.end(); s++){';
+								GEN<<  '         if((found = eq_matrix[i * len + *s])) break;';
+								GEN<<  '       }';
+								GEN<< @'       if(!found) ' $host_name '_' $e '_list.push_back(i);';
+								GEN<<  '     }'
+							 OD;
+							 GEN<< '    };'/
+						   .)
+						*)
+					.)
+					/GEN<< '  } //' end for create lists of shared events;
+					 $single_host:= $host_name/,
+					 
+		shared_events: /GEN<<;
+						GEN<< '  //' check that selected lists are of the same length;
+						GEN<< '  int len_to_compare;'/
+					
+					<* $event_name: $x
+							/GEN<<  @'   len_to_compare = ' $single_host '_' $event_name '_list.size();';
+							 FORALL $h IN $hosts DO
+								IF $h <> $single_host ->
+								GEN<< @'     if(' $h '_' $event_name '_list.size() != len_to_compare) '
+										@ throw failed ';'
+								FI
+							 OD/
+					*>,
+					
+		host_list: /GEN<<;
+					GEN<< '  //' sort the lists/
+					
+					(. (*  (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ ! 
+							   <. var: $host_name .> /$source_name:= $host_name/)
+								-- single host
+							/FORALL $e IN $shared_events DO
+								GEN<< @'     sort_events(' $host_name '_' $e '_list);';
+							 OD/
+						   .)
+						*)
+					.),
+					
+		shared_events: /GEN<<;
+						GEN<< '  //' do the SHARE ALL/
+					
+					<* $event_name: $x
+							/GEN<<  @'   len_to_compare = ' $single_host '_' $event_name '_list.size();';
+							 GEN<<   '   for(int i = 0; i < len_to_compare; i++){';
+							 FORALL $h IN $hosts DO
+								IF $h <> $single_host ->
+								  GEN<< @'     make_equality_complete(' $single_host '_' $event_name '_list[i], '
+											$h '_' $event_name '_list[i]);'
+								FI
+							 OD;
+							 GEN<< '   }'/
+					*>			
+		
+	.>	  							  
+		/GEN<< ;
+		 IF LAST #generate_coordination_class $nesting_depth < 2 ->
+			GEN<< '  create_matrices(); //' to check for axiom violation;
+			GEN<< '  //print_matrices(); //<<<<<<<<<<<<'
+		 FI;
+		 GEN<< '  //' end of SHARE ALL;
+		 LAST #generate_coordination_class $nesting_depth +:= -1/
+	;;
+
+	$a /PRINT (. generation for $a not yet implemented .)/
+##
+
+#generate_schema_class
+-- from $model.elt_list
+
+	/GEN<< '//----' #class_counter() '----';
+	 GEN<< class @ 'SCHEMA_' LAST #AG $model.schema ': public Composite_producer {';
+	 GEN<< 'public:' '//' constructor;
+	 GEN<< '   ' @ 'SCHEMA_' LAST #AG $model.schema '(): Composite_producer(Event_' 
+			LAST #AG $model.schema '){';
+	 GEN<< '      target_event = Schema_node;';
+	 GEN<< '      element =	new Event_producer_ref[ element_count =' 
+					#LEN(LAST #AG $model.elt_list) '];'; 
+	 $element_count:= 0 /
+	 (. (*  (	<. ROOT: $root_name .>
+				/GEN<< '      element[' $element_count 
+						@ ']= new Composite_secondary_producer(Event_' $root_name ');';
+				 $element_count +:= 1 /			!
+				 
+				 ( <. COORDINATE: $work .> ! <. SHARE_ALL: $work .> )
+				/GEN<< '      element[' $element_count 
+						@ ']= new ' $work '_ob(Event_' $work ');';
+				 $element_count +:= 1 /			!
+				  
+				 $any	-- other composition ops here
+			) 
+		*)
+	 .)
+	 /GEN<< '    }';
+	  GEN<< '};//' end class @ 'SCHEMA_' LAST #AG $model.schema;
+	  GEN<< /
+##
+
+#generate_harvest_calls
+	
+	(. /GEN<< '   //' harvesting traces for composite events/
+		(*	$comp_name 
+			/$t:= #class_counter();
+			 GEN<< '   ' LAST #AG $new_composites.$comp_name.work_name @ 'temp_' $t 
+					'; temp_' $t '.harvest();'/
+		*)
+	.)
+##
+
+#harvest_roots
+-- works on $new_root_table
+
+	/GEN<< '   //' harvesting traces for ROOT events/
+	<* $event_name:  
+		<.	work_name:	$work_name,
+			rule_type: ( composite  ! 
+						 ROOT	  
+						 /$t:= #class_counter();
+						  GEN<< '   ' $work_name 
+							@ 'temp_' $t '; temp_' $t '.harvest();'/ )
+		.>
+	*>
+##
+
+#harvest_main_schema
+	/GEN<< '   //' harvesting traces for main schema;
+	 $t:= #class_counter();
+	 GEN<< '   ' @ 'SCHEMA_' LAST #AG $model.schema 
+			' temp_' $t '; temp_' $t '.harvest();';
+			
+	-- generate text file with event traces
+	 GEN<< @ '   temp_' $t '.output_JSON();';
+	 GEN<<   '   gen_end = clock();';
+	 GEN<< @ '   temp_' $t '.show_traces();'/
+##
+
+--------------------------------------------------
+#class_counter
+	/LAST #AG $class_counter +:=1;
+	RETURN COPY(LAST #AG $class_counter)/
+##	

+ 948 - 0
MP2-parser.rig

@@ -0,0 +1,948 @@
+-- MP2_parser.rig   Automated model generator MP2 -> C++
+-- v 2.0
+-- Mikhail Auguston, 03/05/15
+-- last modified 04/05/15
+--
+-- use: parser schema_name output_file scope
+--
+-- takes the source .mp file and creates the intermediate tree
+-- 
+--------------------------------------------------------------
+#MP
+-- ********   Globals:
+-- $scope	-- scope for the model
+-- $main_schema_name  -- from the MP model, used to generate container names
+-- $input_schema_name	-- from the parameters, should be the same
+-- $triggering_events: <* event_name: T *>	
+--		events triggering WHEN, should not appear 
+--		in patterns, but may be shared or coordinated
+--
+-- $atomic_events: <* event_name: T *> -- for generating event list in C++
+-- $already_ordered: <* event_name: T *>  -- for #order_composites_by_dependency
+-- $composite_order: (. (* event_name *) .)	-- retains the composite definition order 
+--											for generating harvest() calls
+-- $this	contains root, composite event or schema name 
+--			for COORDINATE FROM default, reset in #rule
+-- $source_list: <* variable_name: pattern *> -- variables 
+--					defined in nested compositions COORDINATE, ENSURE, NEW
+--					and maintained within schema or BUILD block
+-------------------------------------------
+-- these tables are produced by the 1st pass
+-------------------------------------------
+-- $composites: <* composite_event_name: <. rule_type:	  composite,
+--											work_name:	  work_name,
+--											pattern_list: $pattern_list,
+--											build_block:  $comp_op_list  .>
+--				*> -- composites table
+-- $roots:		<* root_name: <. rule_type:		ROOT,
+--								 work_name:		work_name,
+--								 pattern_list: $pattern_list,
+--								 build_block:  $comp_op_list  .> 
+--				*>		-- roots table
+--
+-- $coordinate_ops: <* work_name: <. operation:			COORDINATE,
+--									 work:				work_name,
+--									 synchronization:	$synchronization,
+--									 source_list:		$coord,
+--									 body:				$body .>  *>  
+-- $share_all_ops:  <* work_name: <. operation:		SHARE_ALL,
+--									 work:			work_name,
+--									 host_list:		$sharing_hosts,
+--									 shared_events:	$shared_events .> *>
+-------------------------------------------
+-- 2nd pass results
+-------------------------------------------
+-- $new_composites: <* composite_event_name: <. rule_type:	  composite,
+--												work_name:	  work_name,
+--												pattern_list: $pattern_list,
+--												build_block:  $comp_op_list,
+--												called_composites: <* $composite_name: T *> .>
+--					*>			-- updated composites table
+-- $new_root_table:	<* root_name: <. rule_type:		ROOT,
+--									 work_name:		work_name,
+--									 pattern_list: $pattern_list,
+--									 build_block:  $comp_op_list,
+--									 called_composites: <* $composite_name: T *> .> 
+--					*>		-- updated roots table
+--
+-- $new_share_all_ops: <* work_name: *>
+-----------------------------------------
+-- $unique_number  -- to keep work names unique
+-- $errors_detected -- stop reporting errors if it becomes > 3
+-------------------------------------------------------------
+
+  $Parm:= #PARM(T); -- list of all parameters
+  $input_schema_name := #IMPLODE( $Parm[1] );
+  $this := $input_schema_name;
+  $input_file	:= #IMPLODE( $input_schema_name '.mp');
+  $output_file	:= #IMPLODE( $Parm[2] ); -- for generation phase
+  IF $Parm[3] ->	
+	$scope	:= $Parm[3]; -- no need to #IMPLODE(), just take the number
+  ELSIF T	  ->	
+	$scope	:= 1;		 -- default scope
+  FI;	
+  OPEN MSG ' ';	--for error messages
+
+  --call C lexer 
+  $Lex:= #CALL_PAS( 35 $input_file 'L+A-U-P-C+p-m+');
+  
+--PRINT $Lex; --<<<<<<<<<<<<<<
+  MSG<< 'MPhoenix parser v.2.0 input from'  $input_file scope $scope
+		Total #LEN($Lex) tokens;
+  	 
+  $unique_number:= 0;
+  $errors_detected:= 0;
+  	 
+  --********** 1st pass, do the parsing, $composites, $roots
+  
+  $complete:= #main_schema( $Lex);
+
+  --*********** 2nd pass, insert/expand composite events,
+  --			create $new_root_table, $new_composites
+ 
+ IF $errors_detected = 0 ->
+	$new_composites :=  #build_rules($composites); -- composites first
+	#detect_recursion($new_composites);
+	$composite_order:= #order_composites_by_dependency($new_composites);
+	$new_root_table :=	 #build_rules($roots);
+	$new_share_all_ops:= #prepare_share_all($share_all_ops);
+	
+ FI;
+
+ IF $errors_detected = 0 -> 
+		--MSG<< 'Parsing completed. Saving result in' $output_file;MSG<<;
+  		$result:=	$complete ++ 
+					-- the contents of $complete returned by #main_schema
+					-- <.	schema:			$id_schema,
+					--		include_list:	$include_list,
+					--		elt_list:		$elt_list	-- roots, composition ops
+					-- .>
+					
+					<. scope:			$scope,
+					 input_file:		$input_file,
+					 roots:				$roots, -- source for comments in C++
+					 composites:		$composites, -- source for comments in C++
+					 atomic_events:		$atomic_events,
+					 new_root_table:	$new_root_table,
+					 new_composites:	$new_composites,
+					 composite_order:	$composite_order,
+					 coordinate_ops:	$coordinate_ops,
+					 share_all_ops:		$new_share_all_ops
+					.>;
+		SAVE $result $output_file;
+--PRINT $result; --<<<<<<<<<<<<<<<<<<<< 
+  ELSIF T -> 	MSG<< 'Errors detected...'
+  FI;
+  
+##
+
+#main_schema
+
+	(.	 SCHEMA ( $id_schema := #IDENT 
+						/LAST #MP $main_schema_name := $id_schema/	!
+				  $x	/#error( $x err1 ); FAIL/ 
+				)
+				  
+		/IF (LAST #MP $input_schema_name <> $id_schema) ->
+			#error( $id_schema err8 ); FAIL 
+		 FI /
+		(*	$include_list !.:= #include_clause  *)
+		(* 
+			$elt_list !.:=
+				(	#rule								! 
+					#composition_operation
+						/LAST #MP $source_list:= NULL/	)
+			( ';' ! $x /#error( $x err4 )/ )
+		 *) 
+		[ #BUILD_block ]		 
+	.)
+	/$filtered_elt_list:= #filter_elt_list($elt_list);
+	 RETURN  <.	schema:			$id_schema,
+				include_list:	$include_list,
+				elt_list:		$filtered_elt_list	-- roots, composition ops
+			.>/
+##
+
+#filter_elt_list
+-- to get rid of plain composite event declarations in schema
+-- leaving only roots and composition ops for schema's class definition
+
+	(. (* ( <. composite: $a .> ! NULL ! $res !.:= $b ) *) .)
+	/RETURN $res/
+##
+
+--------------------------------------------------------------------
+-----1st pass--- rule syntax ---------------------------------------
+--------------------------------------------------------------------
+#include_clause
+	INCLUDE ( $id_schema := #IDENT !
+			  $x /#error( $x err1 ); FAIL/ )
+	( ';' ! $x /#error( $x err4 ); FAIL/ )
+	/RETURN $id_schema/
+##
+
+#rule
+-- globals:
+-- $rule_type
+-- $event_name
+
+	/$rule_type:= composite/ -- the default
+	[ ROOT /$rule_type:= ROOT/]
+	$event_name := #IDENT ':'
+	/LAST #MP $this := $event_name; -- switch default for composition FROM
+	 $defined_event := <. $rule_type: $event_name .>/
+	$patterns:= #pattern_list 
+	[ $build_block := #BUILD_block ]
+	
+	/$rule_body := <. rule_type:	$rule_type,
+					  work_name:	#IMPLODE( 'Comp_' 
+										#unique_number() '_' LAST #MP $main_schema_name),
+					  pattern_list:	$patterns,
+					  build_block:	$build_block
+				   .>;
+	 IF $rule_type = ROOT ->
+		LAST #MP $roots	++:= <. $event_name: $rule_body .>;
+	 ELSIF T ->		-- composite event definition
+		LAST #MP $composites ++:= <. $event_name: $rule_body .>;
+	 FI;
+	 LAST #MP $this := LAST #MP $input_schema_name; -- restore back
+	 RETURN $defined_event /
+##
+
+#pattern_list
+     (* $list!.:= #pattern_unit *) 
+	 /IF #LEN($list) = 1 ->
+		RETURN $list[1]
+	  ELSIF #LEN($list) = 0 ->
+		RETURN <. type: empty .>
+	  FI;
+	  RETURN <. type:	sequence,
+				name:	#IMPLODE(Sq '_'  #unique_number() 
+							'_' LAST #MP $main_schema_name),
+				body:	$list
+			.> /
+##
+
+#pattern_unit
+	-- check look-ahead token
+	V'(	$$<>';' AND $$<>')' AND $$<>'*' AND $$<>'+' AND 
+		$$<>'|' AND $$<>'}' AND $$<>',' AND $$<>']' AND 
+		$$<> BUILD AND $$<> WHEN)
+	$elt:= ( #plain !		-- event name
+			#alternative ! 
+			#iteration !  
+			#iterator_plus !
+			#set !
+			#set_iterator ! 
+			#set_iterator_plus !
+			#optional !
+			#when_clause !
+			$x /#error( $x err2 ); FAIL/
+		   )
+	/RETURN $elt/
+##
+
+#keyword
+	(WHEN ! COORDINATE ! ENSURE ! 'DO' ! 'OD' ! 'FROM') /RETURN T/
+##
+
+#plain
+		V'(NOT #keyword($$))	
+		$Id		
+		/RETURN <.	type: plain,
+					name: $Id
+				.>/
+##
+
+#alternative
+	'('		V'($$<>'*') 
+			(+  [ $probability_list !.:= #probability ]
+				$al!.:= #pattern_list				
+			+'|')
+	')'
+	/ IF #LEN($al) <= 1 ->
+		RETURN $al[1]
+	  FI;
+	  -- return unit
+	  RETURN <.	type:	alternative,
+				name:	#IMPLODE(Alt '_' #unique_number()
+							'_' LAST #MP $main_schema_name),
+							-- to avoid conflicts with INCUDED schemas
+				body:	$al,
+				probability_list: $probability_list
+			.>/
+##
+
+#probability	-- Not implemented yet <<<<<<<<<<<<<<<<<<<<<<<<
+	'<<' 
+	( $Float_number '>>' /RETURN $Float_number/		|
+	  $x					/#error( $x err7 ); FAIL/
+	)
+##
+
+#optional 
+	'[' [ $probability := #probability ] $pl:= #pattern_list ']'
+		/ -- return unit
+		 RETURN <.	type:	optional,
+					name:	#IMPLODE(Opt '_' #unique_number() 
+								'_' LAST #MP $main_schema_name),
+					body:	$pl,
+					probability: $probability 
+				.>/  	
+##
+
+#iteration
+	'(' '*' [ $scope:= #iteration_scope] $pl:= #pattern_list '*' ')'
+	/IF NOT $scope -> 
+		$scope := <. lower_bound: 0, upper_bound: LAST #MP $scope .>
+	 FI;
+	 -- return unit
+	RETURN <.	type:	iterator,
+				name:	#IMPLODE(Itr '_' #unique_number() 
+							'_' LAST #MP $main_schema_name),
+				body:	$pl,
+				iteration_scope: $scope
+		   .>/
+##
+
+#iteration_scope
+	'<'  $lower_bound:= #NUMBER [ '.' '.'  $upper_bound:= #NUMBER ] '>'
+	/IF NOT $upper_bound -> $upper_bound:= COPY($lower_bound) FI;
+	 RETURN <. lower_bound: $lower_bound, upper_bound: $upper_bound .>/
+##
+
+#iterator_plus
+	'(' '+' [$scope:= #iteration_scope] $pl:= #pattern_list '+' ')'
+		/IF NOT $scope -> 
+			$scope := <. lower_bound: 1, upper_bound: LAST #MP $scope .>
+		 FI; 
+		 -- return unit
+		 RETURN <.	type:	iterator_plus,
+					name:	#IMPLODE(Itp '_' #unique_number() 
+								'_' LAST #MP $main_schema_name),
+					body:	$pl,
+					iteration_scope: $scope
+				.>/ 
+##
+		
+#set
+	'{' V'($$<>'*')
+		(+  $al!.:= #pattern_list   + ',') '}'
+		 /
+		  -- return unit
+		  RETURN <.	type:	set,
+					name:	#IMPLODE(Set '_' #unique_number() 
+								'_' LAST #MP $main_schema_name),
+					body:	$al  -- always a list
+				.>/
+##
+
+#set_iterator
+	'{' '*'  [ $scope:= #iteration_scope] $pl:= #pattern_list  '*' '}'
+		/IF NOT $scope -> 
+			$scope := <. lower_bound: 0, upper_bound: LAST #MP $scope .>
+		 FI; 
+		 -- return unit
+		 RETURN <.	type:	set_iterator,
+					name:	#IMPLODE(SetIt '_' #unique_number() 
+								'_' LAST #MP $main_schema_name),
+					body:	$pl,
+					iteration_scope: $scope
+				.>/  
+##
+
+#set_iterator_plus
+	'{' '+' [ $scope:= #iteration_scope] $pl:= #pattern_list  '+' '}'
+		/IF NOT $scope -> 
+			$scope := <. lower_bound: 1, upper_bound: LAST #MP $scope .>
+		 FI;  
+		 -- return unit
+		 RETURN <.	type:	set_iterator_plus,
+					name:	#IMPLODE(SetItp '_' #unique_number() 
+								'_' LAST #MP $main_schema_name),
+					body:	$pl,
+					iteration_scope: $scope
+				.>/  
+##
+
+#when_clause
+	'<' '|' $pl:= #pattern_list 
+		WHEN (+ $wu_list !.:= #when_unit + ',') '|' '>'
+	/RETURN <.	type:	when_clause,
+				body:	$pl,
+				when_units: $wu_list
+			.>/  
+##
+
+#when_unit
+	[ $probability := #probability ]
+	 $event_name := #IDENT '==' '>' $pl:= #pattern_list
+	/LAST #MP $triggering_events ++:= <. $event_name: T .>;
+	 RETURN <. trigger_event:	$event_name,
+			   pattern_list:	$pl,
+			   probability:		$probability 
+			.>/  
+##
+
+------------------------------------
+----- composition operations -------
+------------------------------------
+#composition_operation
+-- globals:
+
+	($res:= #coordinate_composition
+		/LAST #MP $coordinate_ops ++:=	<. $res.work: $res .>/ !
+	 $res:= #shared_composition	
+		/LAST #MP $share_all_ops  ++:=	<. $res.work: $res .>/ !
+	 $res:= #ensure_op										!
+	 $res:= #new_event										)
+	 /RETURN <. $res.operation: $res.work .>/
+##
+
+#new_event
+	NEW /#error( $ err12 )/
+##
+
+#BUILD_block
+	BUILD /#error( $ err12 )/
+	-- add LAST #MP $variables maintenance here <<<<<<<<<<<<<<<<<<<<<<
+	'{'
+	(* $elts !.:= ( #composition_operation
+						/LAST #MP $source_list:= NULL/	!
+					#plain_attribute_declaration		!
+					#event_attribute_declaration		) 
+	* ';')
+	'}'
+			  
+##
+
+#coordinate_composition
+
+	COORDINATE 
+	/ -- maintain the $source_list stack
+	 $old_source_list:= COPY(LAST #MP $source_list)/
+	 /$synchronization:= Synchronous/
+	 ['<' '!' '>' /$synchronization:= Asynchronous/]
+	 
+	(+ $coord++:= #coordination_source 
+		/LAST #MP $source_list ++:= $coord/ +',')
+	('DO' ! $x /#error( $x err9 )/ )
+	(+  $body !.:= ( #add_relation !
+					 #coordinate_composition !
+					 #MAP_composition !
+					 #shared_composition )
+		( ';' ! $x /#error( $x err11 )/ ) 
+	+)
+	('OD' ! $x /#error( $x err10 )/ )
+	/$work:= #IMPLODE( 'Coordinate_' #unique_number() '_' LAST #MP $main_schema_name);
+	 -- restore $source_list stack
+	 LAST #MP $source_list:= $old_source_list;
+	 RETURN <.	operation:			COORDINATE,
+				work:				$work,
+				synchronization:	$synchronization,
+				source_list:		$coord,
+				body:				$body .> /
+##
+
+#coordination_source
+	( $var:= #variable ! $a /#error( $a err14 ); FAIL/)
+	( ':' ! $x /#error( $x err13 ); FAIL/ )
+	/IF LAST #MP $source_list.$var ->
+		#error( $var err19 ); FAIL
+	FI/
+
+	$pattern:= #selection_pattern
+	[ 'FROM' $from:= ( 'this' ! 
+					   $v:= #variable 
+					   /IF	NOT LAST #MP $source_list.$v ->
+								#error( $v err17 ); FAIL
+						FI/ !
+						#root_name 
+					 )]
+	-- the default for FROM is 'this'
+	/IF NOT $from OR $from = this -> 
+		$from:= <. comp: COPY(LAST #MP $this) .>
+	 ELSIF NOT #TREE($from) ->
+		$from:= <. var: $v .>
+	 FI;
+	 RETURN <.	$var: <. selection_pattern:	$pattern,
+						 from:				$from	.> 
+			.>/
+##
+
+#variable
+	$a 
+	/$b:= #EXPLODE($a);
+	 IF $b[1] <> '$' -> FAIL FI;
+	 $b[1]:= NULL;
+	 RETURN #IMPLODE($b '_variable')/
+##
+
+#selection_pattern
+	$plist!.:= $Id /RETURN $plist/;;
+	
+	'(' (+ $plist!.:= $Id + '|') ')' /RETURN $plist/
+##
+
+#root_name
+	V'(NOT #keyword($$)) 
+	$Id
+	/IF LAST #MP $roots.$Id OR 
+		( LAST #rule $event_name = $Id AND LAST #rule $rule_type = ROOT) OR
+		$Id = LAST #MP $input_schema_name ->
+		RETURN <. comp: $Id .>
+	ELSIF T ->
+		#error( $Id err15 );
+		FAIL
+	FI/
+##
+
+#add_relation
+	ADD 
+	(+  $v1:= #variable
+		/IF NOT LAST #MP $source_list.$v1 ->
+			#error( $v1 err17 ); FAIL
+		 FI;/
+		$relation:= ( 'IN' ! PRECEDES ! CONTAINS ! FOLLOWS ! $x /#error( $x err16 ); FAIL/)
+		$v2:= #variable
+		/IF NOT LAST #MP $source_list.$v2 ->
+			#error( $v2 err17 ); FAIL
+		 FI;
+		 $res!.:= <. first:		$v1,
+					 second:	$v2,
+					 relation:	$relation .>/
+	+ ',')
+	/RETURN <. operation:		ADD,
+			   relation_list:	$res .>/
+##
+
+#MAP_composition 
+	MAP /#error( $ err12 ); FAIL/
+##
+
+#shared_composition
+
+	(+ 
+		(+ 
+			$from:= ( 'this' ! 
+						$v:= #variable 
+						/IF	NOT LAST #MP $source_list.$v ->
+							#error( $v err17 ); FAIL
+						 FI/ !
+						 #root_name 
+					)
+			/IF $from = this -> 
+				$from:= <. comp: COPY(LAST #MP $this) .>
+			 ELSIF NOT #TREE($from) ->
+				$from:= <. var: $v .>
+			 FI;
+			 $sharing_host !.:= $from/
+		+ #exclusive_union )
+	 
+	   /$sharing_hosts !.:= $sharing_host;
+	    $sharing_host:= NULL/
+	+ ',')
+
+	'SHARE' 'ALL'
+	(+ $Id /$shared_events ++:= <. $Id: T .>/ + ',')
+	
+	/$work:= #IMPLODE( 'ShareAll_' #unique_number() '_' LAST #MP $main_schema_name);
+	 RETURN <.	operation:		SHARE_ALL,
+				work:			$work,
+				host_list:		$sharing_hosts,
+				shared_events:	$shared_events .>/
+##
+
+#exclusive_union
+	'|' '+' '|'
+##
+
+#ensure_op
+	ENSURE /#error( $ err12 ); FAIL/
+##
+
+------------------------------------
+-----	 event attributes    -------
+------------------------------------
+
+#plain_attribute_declaration 
+
+##
+
+#event_attribute_declaration
+
+##
+
+------------------------------------------------------------------------------
+--------- 2nd pass, updates of $composites and $roots
+--------- identifying composite events
+------------------------------------------------------------------------------
+
+-- put composite events into event patterns to distinguish them from plain atoms
+-- check that no recursion happens (by assembling a list of all called composites in depth)
+-- flatten iterations by scope, replacing with alternatives
+-- replace optional with alternative
+-- expand WHEN clauses macro
+-- estimate segment count
+------------------------------------------------------------------------------
+
+#build_rules
+-- returns updated rule tables
+---------------------------------
+
+-- Globals:		
+--	$rule_id
+--  $called_composites: <* $composite_name: T *> -- composite rules called from $rule_id
+--  $inside_when   -- is T when process pattern list in WHEN block
+---------------------------------------------
+
+	<* $rule_id: <. rule_type:	$rule_type,
+					work_name:	$work_name,
+					[build_block: $comp_op_list],
+					pattern_list: $b:= #build_element  
+						/$res++:= <. $rule_id: 
+									<.	rule_type:			$rule_type,
+										work_name:			$work_name,
+										pattern_list:		$b,
+										build_block:		$comp_op_list, 
+										called_composites:	$called_composites 
+									.> 
+								  .>;
+						 $called_composites	:= NULL;
+						 $comp_op_list		:= NULL /
+				.>
+	 *>
+	/RETURN $res/
+##
+
+#build_element
+-- traverses the initial tree, 
+-- marks composite events to distinguish them from atoms
+-- flattening iterations by scope, replacing with alternative
+-- replacing optional with alternative
+-- checking that no recursion happens, ONLY SIMPLE RECURSION IS CHECKED
+--
+-- returns (modified) element
+----------------
+--replaces type for 'composite', instead of "plain"
+	<.	type: plain,
+		name: $Id    .>
+		
+	/IF LAST #build_rules $inside_when AND LAST #MP $triggering_events.$Id  ->
+		#error( $Id err3); FAIL -- trigger event should not appear in pattern list
+	 FI;
+	 
+	 IF LAST #MP $roots.$Id ->
+		#error( $Id err5); FAIL --root event should not appear in rule body
+	 FI;
+	 
+	-- IF $Id = LAST #build_rules $rule_id ->
+	 -- detects simple recursion
+	--	#error( $Id err6); FAIL --event should not appear recursively in rule body
+	-- FI;
+
+	 IF LAST #MP $composites.$Id  ->
+		LAST #build_rules $called_composites ++:= <. $Id: T .>;
+		RETURN <. type: composite,
+				  name: $Id 
+			   .>
+	 FI;
+
+	 LAST #MP $atomic_events ++:= <. $Id: T .>;
+	 RETURN $ /;;
+-------------
+
+	<.	type:	$type:= (sequence ! alternative),
+		name:	$work_name,
+		body:	(. (* $b !.:= #build_element *) .),
+		[probability_list: $probability_list]
+	.> 	
+	/RETURN <.	type:	$type,
+				name:	$work_name,
+				body:	$b,
+				probability_list: $probability_list
+			.>/;;
+
+----------------
+	-- this requires to apply scope limit and transform into alternative pattern
+	<.	type:		$type:= ( (iterator ! iterator_plus) /$new_type:= sequence/ !
+							  (set_iterator ! set_iterator_plus) /$new_type:= set/ ),
+		name:			 $name,
+		body:			 $b:= #build_element,
+		iteration_scope: <. lower_bound: $lower_bound, 
+							upper_bound: $upper_bound .> 
+	.>
+	/ -- create alternatives	for iterations lower .. upper
+	 $this_lower_bound := COPY($lower_bound);
+	 IF $this_lower_bound = 0 -> 
+		$new_body!.:= <. type: empty .>;
+		$this_lower_bound +:=1
+	 FI;
+	 IF  $this_lower_bound = 1 AND $this_lower_bound <= $upper_bound -> 
+		$new_body!.:= $b;
+		$this_lower_bound +:=1
+	 FI;
+	 	
+	 LOOP -- at this point $this_lower_bound > 1
+		$x := COPY($this_lower_bound);
+		-- now to create sequences of >=2 $b instancies
+		IF $x > $upper_bound -> BREAK FI;
+		-- create a sequence of $lower_bound instances of $b
+		$a := NULL;
+		LOOP
+			IF $x = 0 -> BREAK FI;
+			$a!.:= $b;
+			$x +:= -1
+		END;
+		-- if new type = set, no permutation is needed, because all are identical
+
+		$new_body!.:= <. type: $new_type, 
+						 name: #IMPLODE(Ct '_' #unique_number() 
+									'_' LAST #MP $main_schema_name), 
+						 body: $a
+					 .>;
+		$this_lower_bound +:= 1
+	END;
+	
+	IF #LEN($new_body) = 1 ->
+		$new_body := $new_body[1];
+		RETURN $new_body
+	FI;
+	
+	RETURN <.	type: alternative, 
+				name: $name, 
+				body: $new_body .>
+	/;;
+	
+--------------
+	<.	type:	optional,
+		name:	$name,
+		body:	$b:= #build_element
+	.>
+	/RETURN <. type: alternative, 
+			   name:	$name, 
+			   body: (. <. type: empty .> $b .)
+			.>/;;
+	
+--------------
+	<.	type: empty .> /RETURN $/;;
+	
+--------------
+	<.	type:	set,
+		name:	$name,
+		body:	(. (* $b!.:= #build_element *) .)
+	.> 	
+	/IF #LEN($b) = 1 ->
+		RETURN <. type:	set,
+				  name:	$name,
+				  body:	$b
+			   .>
+	ELSIF T ->
+	 -- find all permutations of body elements and assemble an alternative of them
+	 -- in fact, implement interlacing to support shared mapping
+		$permutations:= #find_all_permutations($b);
+		RETURN <.	type: alternative, 
+					name: $name, 
+					body: $permutations .>
+	FI /;;
+--------------
+
+	<.	type:	when_clause /LAST #build_rules $inside_when := T/,
+		body:	$pl,
+		when_units: $wu_list
+	.>
+	/LAST #build_rules $inside_when := NULL;
+	-- transform WHEN pattern by applying CUT macro --<<<<<<<<<<<<<<<<<<<<<
+	RETURN $ --<<<<<<<<<<<<<<<<<<<<
+	/;;
+--------------
+
+	$x	 /PRINT (. '****#build_element*****' build for type $x.type not yet implemented for $x .);
+		  RETURN EMPTY/
+##
+
+#find_all_permutations
+-- find all permutations of shared events in the element_list, make a set for each,
+-- and return the list of sets
+
+	$elt_list
+	/
+	-- get all index permutations
+	$index_perms:= #permutations(#LEN($elt_list));
+	FORALL $indexes IN $index_perms DO
+		$new_list:= NULL;
+		FORALL $ind IN $indexes DO
+			$new_list !.:= $elt_list[$ind]
+		OD;
+		$new_body !.:=	<.	type: set, 
+							name: #IMPLODE( 'Set_' #unique_number() 
+									'_' LAST #MP $main_schema_name), 
+							body: $new_list 
+						.>
+	OD;
+	RETURN $new_body /
+##
+
+#permutations
+-- return list of all permutations for integers 1..n
+	$n
+	/IF $n <= 1 -> RETURN (. (. 1 .) .) FI;
+	 $prev:= #permutations($n - 1);
+	 FORALL $p IN $prev DO
+		$x:= 1;
+		$len:= #LEN($p);
+		-- insert n at place x in p
+		LOOP
+			IF $x > $len -> BREAK FI;
+			$y:= 1;
+			$r:= NULL;
+			FORALL $e IN $p DO
+				IF $y = $x -> $r !.:= $n FI;
+				$r !.:= $e;
+				$y +:= 1
+			OD;
+			$res !.:= $r;
+			$x +:=1
+		END;
+		$item:= NULL; -- unfortunately COPY($p)!.$n does not work!
+		FORALL $z IN $p DO
+			$item !.:= $z
+		OD; 
+		$item !.:= $n;
+		$res !.:= $item;
+	 OD;
+	 RETURN $res /
+##
+
+#detect_recursion
+-- global: $already_called
+
+	<* $event_name: <. [ called_composites: 
+									/$already_called:= NULL/
+									<* $callee: $x 
+							/$already_called ++:= <. $callee: T .>;
+							 IF $event_name = $callee ->
+								#error( $event_name err6 ); FAIL
+							 FI;
+							 
+							 IF LAST #MP $new_composites.$callee.called_composites ->
+								#check_recursive_call_in_depth( LAST #MP $new_composites.$callee )
+							 FI/
+									*> ] 
+					.>
+	*>
+##
+
+#check_recursive_call_in_depth
+	<. called_composites: <* $callee: $x 
+							/IF LAST #detect_recursion $already_called.$callee ->
+								#error( $callee err6 ); FAIL
+							 FI;
+							 LAST #detect_recursion $already_called ++:= <. $callee: T .>;
+							 IF LAST #MP $new_composites.$callee.called_composites ->
+								#check_recursive_call_in_depth( LAST #MP $new_composites.$callee )
+							 FI/
+						   *>
+	.>
+##
+
+#order_composites_by_dependency
+
+	<* $event_name: <. [ called_composites: 
+							<* $callee: $x 
+								/IF LAST #MP $new_composites.$callee.called_composites ->
+									#find_dependencies_in_depth( LAST #MP $new_composites.$callee )
+								FI;
+								IF NOT LAST #MP $already_ordered.$callee ->
+									LAST #MP $already_ordered ++:= <. $callee: T .>;
+									$ordered_list !.:= $callee
+								FI /
+							*> ] 
+					.>
+					-- all callees have been put on the list
+					/IF NOT LAST #MP $already_ordered.$event_name ->
+						LAST #MP $already_ordered ++:= <. $event_name: T .>;
+						$ordered_list !.:= $event_name
+					 FI/ 
+	*>
+	/RETURN $ordered_list/
+##
+
+#find_dependencies_in_depth
+	<. called_composites: 
+							<* $callee: $x 
+								/IF LAST #MP $new_composites.$callee.called_composites ->
+									#find_dependencies_in_depth( LAST #MP $new_composites.$callee )
+								FI;
+								IF NOT LAST #MP $already_ordered.$callee ->
+									LAST #MP $already_ordered ++:= <. $callee: T .>;
+									$ordered_list !.:= $callee
+								FI /
+							*> 
+	.>
+##
+
+#prepare_share_all
+	<* $work:
+			<.	host_list:		$sharing_hosts,
+				shared_events:	/$shared_events:= NULL/
+								<* $event_name: $x
+									/IF LAST #MP $composites.$event_name ->
+										$shared_events ++:= <. $event_name: composite .>
+									 ELSIF LAST #MP $atomic_events.$event_name ->
+										$shared_events ++:= <. $event_name: atomic .>
+									 ELSIF T ->
+										#error( $event_name err18 ); FAIL
+									 FI/
+								*> 
+			.>
+			/$res ++:= <. $work: 
+							<. operation: SHARE_ALL,
+							   host_list: $sharing_hosts,
+							   shared_events:	$shared_events .>
+							.>/
+	*>
+	/RETURN $res/
+##
+	
+------------- auxiliary rules -------------------
+#error
+	$a  /IF LAST #MP $errors_detected > 2 -> FAIL FI;
+		 $line := #CALL_PAS( 4 $a ) DIV 80;
+		 $col  := #CALL_PAS( 4 $a ) MOD 80;
+		 MSG<< '*** error:';
+		 IF $line <> 0 ->
+			MSG<] at $line ':' $col
+		 FI;
+		 LAST #MP $errors_detected +:= 1/
+		 
+	( err1 /MSG<] wrong schema name $a identifier expected/ !
+	  err2 /MSG<] wrong event pattern $a / !
+	  err3 /MSG<] trigger event $a should not appear in WHEN pattern list / !
+	  err4 /MSG<] detected around token $a/ !
+	  err5 /MSG<] root event $a should not appear in rule body/ !
+	  err6 /MSG<] recursion for event $a is detected/ !
+	  err7 /MSG<] syntax error in probability definition detected at $a/ !
+	  err8 /MSG<] schema name $a should be the same as input parameter/ !
+	  err9 /MSG<] keyword 'DO' is expected in COORDINATE when actual token is $a / !
+	  err10 /MSG<] keyword 'OD' is expected in COORDINATE when actual token is $a / !
+	  err11 /MSG<] semicolon is expected when actual token is $a / !
+	  err12 /MSG<] construct at token $a is not yet implemented/ !
+	  err13 /MSG<] ':' is expected when actual token is $a / !
+	  err14 /MSG<] incorrect variable name $a in the COORDINATE source / !
+	  err15 /MSG<] derivation for root $a should be completed before composition/ !
+	  err16 /MSG<] wrong relation name $a in the ADD composition/ !
+	  err17 /MSG<] variable name $a is undefined/ !
+	  err18 /MSG<] shared event $a has not been defined in any grammar rule / !
+	  err19 /MSG<] variable name $a has been defined twice/ !
+
+	  $any /MSG<< at token $a/ 
+	)
+##
+--------------------------------------------------
+#unique_number
+	/LAST #MP $unique_number +:=1;
+	RETURN COPY(LAST #MP $unique_number)/
+##	
+
+

BIN
MP2-syntax.pdf


+ 43 - 0
Summer2015.mp

@@ -0,0 +1,43 @@
+/*//————————————————————————————
+// 	 		  Actors
+//————————————————————————————*/
+SCHEMA Summer2015
+
+ROOT You:	Read_Flyer
+                Get_Intrigued 
+                Check_Out_Website
+                ( Like_MP | Decide_MP_Not_for_Me );
+     
+       Like_MP: Email_Dr_G
+                Discuss_Research_Interests
+                Propose_a_Fascinating_Problem_to_Model
+                Do_an_Awesome_Senior_Project;
+
+Do_an_Awesome_Senior_Project: (* ( accomplish_a_task | got_a_great_idea ) 
+				 [ discuss_some_questions ] *);
+                
+ROOT Dr_G:  ( 	Set_Up_Meeting
+                Discuss_Research_Interests
+                Assess_MP_as_a_Good_Fit
+                Mentor_an_Awesome_Senior_Project  |
+	        Does_something_else );
+
+Mentor_an_Awesome_Senior_Project: (* discuss_some_questions *);
+
+/*//————————————————————————————
+// 		        Interactions
+//————————————————————————————*/
+
+COORDINATE 	$a: Email_Dr_G			FROM You, 
+		$b: Set_Up_Meeting		FROM Dr_G
+		DO ADD $a PRECEDES $b; OD;
+
+COORDINATE 	$a: Propose_a_Fascinating_Problem_to_Model  FROM You, 
+		$b: Assess_MP_as_a_Good_Fit		    FROM Dr_G
+		DO ADD $a PRECEDES $b; OD;
+
+COORDINATE 	$a: Assess_MP_as_a_Good_Fit  FROM Dr_G, 
+		$b: Do_an_Awesome_Senior_Project  FROM You
+		DO ADD $a PRECEDES $b; OD;
+
+You, Dr_G SHARE ALL discuss_some_questions;

+ 314 - 0
Swarm2.mp

@@ -0,0 +1,314 @@
+/*//————————————————————————————
+// 	Kristin Giammarco
+//	11 February 2015 - Initial Model Started by KGiammarco
+//	12 February 2015 - Made Executable for Eagle6 KGiammarco
+//      21 Feb 2015 - Interactions 12, 13, 14a, 14b, 15 causing execution issues,
+//                      tried retyping Interaction 15 with no success
+//      Based on "Swarm CONOPs" Draft 11 February 2015 
+//---------------------------------------------------------
+
+	notes:
+1. COORDINATE should be applied to roots, hence
+	I’ve replaced UAV (which is just a composite event) with SWARM
+2. Swarm is a set (no ordering), this requires Asynchronous COORDINATE <!>
+
+3. Heavy coordination implies that even for scope 2 there is only 1 trace. 
+	Need to look carefully where in the model appears a coordination 
+	with root that allows only a single event participating in the COORDINATE.
+//---------------------------------------------------------
+// 	 		Main Actors
+//————————————————————————————*/
+SCHEMA Swarm2
+
+ROOT Flight_Crew: 	Conduct_PreMission_Briefing
+			(* PreFlight_UAV *)
+			Propose_Staging_Plans
+			(* Request_UAV_Launch_Permission
+			   Launch_UAV
+			   Assess_Flight_Behavior
+			   Confirm_Nominal_Flight_Behavior
+			   Stage_UAV_for_Ingress *)
+
+			   Alert_All_UAVs_Staged
+			  (* Observe_New_UAV_in_Recovery_List
+			     [ Receive_Recovery_Prioritization_List ]  
+			     Recover_UAV 
+			     Retrieve_UAV
+			     Alert_RC_UAV_Landing *)
+			   Confirm_UAVs_Recovered_Retrieved
+			   Conduct_PostMission_Hotwash;
+
+
+ROOT Swarm: 		{+ UAV +};
+
+/* composite event */
+   UAV:			Undergo_PreFlight
+			Launch
+			Report_Flight_Status
+			Confirm_Staged_for_Ingress
+			Confirm_Ingress_SubSwarm_ID
+			Commence_Mission
+			Confirm_Egress_SubSwarm_ID
+			Confirm_Staged_for_Egress
+			Land;
+
+COORDINATE <!>	$a: PreFlight_UAV			FROM Flight_Crew, 
+		$b: Undergo_PreFlight			FROM Swarm
+		DO ADD $a PRECEDES $b; OD;  		/* 2 */
+
+COORDINATE <!>	$a: Launch_UAV				FROM Flight_Crew, 
+		$b: Launch 				FROM Swarm
+		DO ADD $a PRECEDES $b; OD;		/* 6 */
+
+COORDINATE <!>	$a: Report_Flight_Status 		FROM Swarm, 
+		$b: Assess_Flight_Behavior		FROM Flight_Crew
+		DO ADD $a PRECEDES $b; OD;		/* 7 */
+
+COORDINATE <!>	$a: Stage_UAV_for_Ingress		FROM Flight_Crew, 
+		$b: Confirm_Staged_for_Ingress		FROM Swarm
+		DO ADD $a PRECEDES $b; OD;		/* 8a */
+
+COORDINATE <!>	$a: Confirm_Staged_for_Egress 		FROM Swarm, 
+		$b: Observe_New_UAV_in_Recovery_List	FROM Flight_Crew
+		DO ADD $a PRECEDES $b; OD;		/* 12 */
+
+COORDINATE <!>	$a: Recover_UAV				FROM Flight_Crew, 
+		$b: Land 				FROM Swarm
+		DO ADD $b PRECEDES $a; OD;		/* 14a */
+
+
+ROOT Mission_Commander:	Conduct_PreMission_Briefing
+                        Confirm_Staging_Plans
+			Confirm_Swarm_Mission_Plan
+			(* Grant_UAV_Launch_Permission *)
+			Conduct_PostMission_Hotwash;
+
+COORDINATE 	$a: Propose_Staging_Plans		FROM Flight_Crew, 
+		$b: Confirm_Staging_Plans		FROM Mission_Commander
+		DO ADD $a PRECEDES $b; OD;		/* 3 */
+
+COORDINATE 	$a: Request_UAV_Launch_Permission	FROM Flight_Crew, 
+		$b: Grant_UAV_Launch_Permission		FROM Mission_Commander
+		DO ADD $a PRECEDES $b; OD;		/* 5 */
+
+COORDINATE 	$a: Confirm_UAVs_Recovered_Retrieved	FROM Flight_Crew, 
+		$b: Conduct_PostMission_Hotwash		FROM Mission_Commander
+		DO ADD $a PRECEDES $b; OD;		/* 16a */
+
+
+ROOT Swarm_Operator:	Conduct_PreMission_Briefing
+			Propose_Swarm_Mission_Plan
+			(* Assign_Ingress_SubSwarmID *)
+			Command_Swarm_to_Commence_Mission
+			(* Assign_Egress_SubSwarmID *)
+			Provide_Recovery_Prioritization_List
+			Conduct_PostMission_Hotwash;
+			   
+COORDINATE 	$a: Propose_Swarm_Mission_Plan		FROM Swarm_Operator, 
+		$b: Confirm_Swarm_Mission_Plan		FROM Mission_Commander
+		DO ADD $a PRECEDES $b; OD;		/* 4 */
+
+COORDINATE <!>	$a: Confirm_Staged_for_Ingress		FROM Swarm, 
+		$b: Assign_Ingress_SubSwarmID		FROM Swarm_Operator
+		DO ADD $a PRECEDES $b; OD;		/* 8b */
+
+COORDINATE <!>	$a: Assign_Ingress_SubSwarmID		FROM Swarm_Operator, 
+		$b: Confirm_Ingress_SubSwarm_ID		FROM Swarm
+		DO ADD $a PRECEDES $b; OD;		/* 9 */
+
+COORDINATE 	$a: Alert_All_UAVs_Staged		FROM Flight_Crew,
+		$b: Command_Swarm_to_Commence_Mission	FROM Swarm_Operator
+		DO ADD $a PRECEDES $b; OD;		/* 10a */
+
+COORDINATE <!>	$a: Command_Swarm_to_Commence_Mission	FROM Swarm_Operator, 
+		$b: Commence_Mission			FROM Swarm
+		DO ADD $a PRECEDES $b; OD;		/* 10b */
+
+COORDINATE <!>	$a: Assign_Egress_SubSwarmID		FROM Swarm_Operator, 
+		$b: Confirm_Egress_SubSwarm_ID		FROM Swarm
+		DO ADD $a PRECEDES $b; OD;		/* 11 */
+
+COORDINATE 	$a: Provide_Recovery_Prioritization_List	FROM Swarm_Operator, 
+		$b: Receive_Recovery_Prioritization_List	FROM Flight_Crew
+		DO ADD $a PRECEDES $b; OD;		/* 13 */
+
+ROOT Range_Control: 	(* Receive_UAV_Landing_Notification *);
+
+COORDINATE 	$a: Alert_RC_UAV_Landing		FROM Flight_Crew, 
+		$b: Receive_UAV_Landing_Notification	FROM Range_Control
+		DO ADD $a PRECEDES $b; OD;		/* 15 */
+
+ROOT Safety_Coordinator:	Conduct_PreMission_Briefing
+			        Conduct_PostMission_Hotwash;
+
+/*
+//---------------------------------------------------------
+// 		         Interactions
+//		SHARE ALL Simulating COORDINATE
+//---------------------------------------------------------
+
+Mission_Commander, Flight_Crew, Swarm_Operator, Safety_Coordinator SHARE ALL Conduct_PreMission_Briefing;
+*/
+
+/*
+ROOT    Interaction2: (* (PreFlight_UAV   Undergo_PreFlight) *);
+Flight_Crew,   Interaction2     SHARE ALL	PreFlight_UAV;
+UAV, Interaction2       	SHARE ALL 	Undergo_PreFlight;
+
+
+ROOT    Interaction3: (* (Propose_Staging_Plans   Confirm_Staging_Plans) *);
+Flight_Crew,   Interaction3     	SHARE ALL	Propose_Staging_Plans;
+Mission_Commander, Interaction3       	SHARE ALL 	Confirm_Staging_Plans;
+
+
+//COORDINATE 	$a: Propose_Swarm_Mission_Plan		FROM Swarm_Operator, 
+//		$b: Confirm_Swarm_Mission_Plan		FROM Mission_Commander
+//		DO ADD $a PRECEDES $b OD;		//4
+
+ROOT    Interaction4: (* (Propose_Swarm_Mission_Plan   Confirm_Swarm_Mission_Plan) *);
+Swarm_Operator,   Interaction4	    	SHARE ALL	Propose_Swarm_Mission_Plan;
+Mission_Commander, Interaction4       	SHARE ALL 	Confirm_Swarm_Mission_Plan;
+
+
+//COORDINATE 	$a: Request_UAV_Launch_Permission	FROM Flight_Crew, 
+//		$b: Grant_UAV_Launch_Permission		FROM Mission_Commander
+//		DO ADD $a PRECEDES $b OD;		//5
+
+ROOT    Interaction5: (* (Request_UAV_Launch_Permission   Grant_UAV_Launch_Permission) *);
+Flight_Crew,   Interaction5     	SHARE ALL	Request_UAV_Launch_Permission;
+Mission_Commander, Interaction5       	SHARE ALL 	Grant_UAV_Launch_Permission;
+
+
+//COORDINATE 	$a: Launch_UAV				FROM Flight_Crew, 
+//		$b: Launch 				FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//6
+
+ROOT    Interaction6: (* (Launch_UAV   Launch) *);
+Flight_Crew,   Interaction6     SHARE ALL	Launch_UAV;
+UAV, Interaction6       	SHARE ALL 	Launch;
+
+
+//COORDINATE 	$a: Report_Flight_Status 		FROM UAV, 
+//		$b: Assess_Flight_Behavior		FROM Flight_Crew
+//		DO ADD $a PRECEDES $b OD;		//7
+
+ROOT    Interaction7: (* (Report_Flight_Status    Assess_Flight_Behavior) *);
+UAV,   Interaction7     	SHARE ALL	Report_Flight_Status;
+Flight_Crew, Interaction7       SHARE ALL 	Assess_Flight_Behavior;
+
+
+//COORDINATE 	$a: Stage_UAV_for_Ingress		FROM Flight_Crew, 
+//		$b: Confirm_Staged_for_Ingress		FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//8a
+
+ROOT    Interaction8a: (* (Stage_UAV_for_Ingress   Confirm_Staged_for_Ingress) *);
+Flight_Crew,   Interaction8a    SHARE ALL	Stage_UAV_for_Ingress;
+UAV, Interaction8a	      	SHARE ALL 	Confirm_Staged_for_Ingress;
+
+
+//COORDINATE 	$a: Confirm_Staged_for_Ingress		FROM UAV, 
+//		$b: Assign_Ingress_SubSwarmID		FROM Swarm_Operator
+//		DO ADD $a PRECEDES $b OD;		//8b
+
+ROOT    Interaction8b: (* (Confirm_Staged_for_Ingress    Assign_Ingress_SubSwarmID) *);
+UAV,   Interaction8b     	SHARE ALL	Confirm_Staged_for_Ingress;
+Swarm_Operator, Interaction8b   SHARE ALL 	Assign_Ingress_SubSwarmID;
+
+
+//COORDINATE 	$a: Assign_Ingress_SubSwarmID		FROM Swarm_Operator, 
+//		$b: Confirm_Ingress_SubSwarm_ID		FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//9
+
+ROOT    Interaction9: (* (Assign_Ingress_SubSwarmID    Confirm_Ingress_SubSwarm_ID) *);
+Swarm_Operator, Interaction9  	SHARE ALL	Assign_Ingress_SubSwarmID;
+UAV, Interaction9   		SHARE ALL 	Confirm_Ingress_SubSwarm_ID;
+
+
+//COORDINATE 	$a: Alert_All_UAVs_Staged		FROM Flight_Crew
+//		$b: Command_Swarm_to_Commence_Mission	FROM Swarm_Operator
+//		DO ADD $a PRECEDES $b OD;		//10a
+
+ROOT    Interaction10a: (* (Alert_All_UAVs_Staged   Command_Swarm_to_Commence_Mission) *);
+Flight_Crew,   Interaction10a    SHARE ALL	Alert_All_UAVs_Staged;
+Swarm_Operator, Interaction10a	 SHARE ALL 	Command_Swarm_to_Commence_Mission;
+
+
+//COORDINATE 	$a: Command_Swarm_to_Commence_Mission	FROM Swarm_Operator, 
+//		$b: Commence_Mission			FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//10b
+
+ROOT    Interaction10b: (* (Command_Swarm_to_Commence_Mission    Commence_Mission) *);
+Swarm_Operator, Interaction10b  SHARE ALL	Command_Swarm_to_Commence_Mission;
+UAV, Interaction10b   		SHARE ALL 	Commence_Mission;
+
+
+//COORDINATE 	$a: Assign_Egress_SubSwarmID		FROM Swarm_Operator, 
+//		$b: Confirm_Egress_SubSwarm_ID		FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//11
+
+ROOT    Interaction11: (* (Assign_Egress_SubSwarmID    Confirm_Egress_SubSwarm_ID) *);
+Swarm_Operator, Interaction11  	SHARE ALL	Assign_Egress_SubSwarmID;
+UAV, Interaction11   		SHARE ALL 	Confirm_Egress_SubSwarm_ID;
+
+
+//COORDINATE 	$a: Confirm_Staged_for_Egress 		FROM UAV, 
+//		$b: Observe_New_UAV_in_Recovery_List	FROM Flight_Crew
+//		DO ADD $a PRECEDES $b OD;		//12
+
+//ROOT    Interaction12: (* (Confirm_Staged_for_Egress    Observe_New_UAV_in_Recovery_List) *);
+//UAV,   Interaction12     	SHARE ALL	Confirm_Staged_for_Egress;
+//Flight_Crew, Interaction12     	SHARE ALL 	Observe_New_UAV_in_Recovery_List;
+
+
+//COORDINATE 	$a: Provide_Recovery_Prioritization_List	FROM Swarm_Operator, 
+//		$b: Receive_Recovery_Prioritization_List	FROM Flight_Crew
+//		DO ADD $a PRECEDES $b OD;		//13
+
+//ROOT    Interaction13: (* (Provide_Recovery_Prioritization_List    Receive_Recovery_Prioritization_List) *);
+//Swarm_Operator, Interaction13  	SHARE ALL	Provide_Recovery_Prioritization_List;
+//Flight_Crew, Interaction13   	SHARE ALL 	Receive_Recovery_Prioritization_List;
+
+
+//COORDINATE 	$a: Recover_UAV				FROM Flight_Crew, 
+//		$b: Land 				FROM UAV
+//		DO ADD $a PRECEDES $b OD;		//14a
+
+//ROOT    Interaction14a: (* (Recover_UAV	   Land) *);
+//Flight_Crew,   Interaction14a   SHARE ALL	Recover_UAV;
+//UAV, Interaction14a       	SHARE ALL 	Land;
+
+
+//COORDINATE 	$a: Land 				FROM UAV, 
+//		$b: Retrieve_UAV			FROM Flight_Crew
+//		DO ADD $a PRECEDES $b OD;		//14b
+
+//ROOT    Interaction14b: (* (Land    Retrieve_UAV) *);
+//UAV,   Interaction14b     	SHARE ALL	Land;
+//Flight_Crew, Interaction14b     SHARE ALL 	Retrieve_UAV;
+
+
+//COORDINATE 	$a: Alert_RC_UAV_Landing		FROM Flight_Crew, 
+//		$b: Receive_UAV_Landing_Notification	FROM Range_Control
+//		DO ADD $a PRECEDES $b OD;		//15
+
+//ROOT Interaction15: (* (Alert_RC_UAV_Landing  Receive_UAV_Landing_Notification) *);
+//Flight_Crew, Interaction15    SHARE ALL  Alert_RC_UAV_Landing;
+//Range_Control, Interaction15  SHARE ALL  Receive_UAV_Landing_Notification;
+
+ROOT Interaction15: (* (Alert_RC_UAV_Landing Receive_UAV_Landing_Notification) *);
+Flight_Crew, Interaction15 SHARE ALL Alert_RC_UAV_Landing;
+Range_Control, Interaction15 SHARE ALL Receive_UAV_Landing_Notification;
+
+//COORDINATE 	$a: Confirm_UAVs_Recovered_Retrieved	FROM Flight_Crew, 
+//		$b: Conduct_PostMission_Hotwash	FROM Mission_Commander
+//		DO ADD $a PRECEDES $b OD;		//16a
+
+ROOT    Interaction16a: (* (Confirm_UAVs_Recovered_Retrieved   Conduct_PostMission_Hotwash) *);
+Flight_Crew, Interaction16a     	SHARE ALL	Confirm_UAVs_Recovered_Retrieved;
+Mission_Commander, Interaction16a	SHARE ALL 	Conduct_PostMission_Hotwash;
+
+
+Mission_Commander, Flight_Crew, Swarm_Operator, Safety_Coordinator  	
+				SHARE ALL 	Conduct_PostMission_Hotwash;
+							//16b
+*/

+ 13 - 0
etude14.mp

@@ -0,0 +1,13 @@
+/* basic test for COORDINATE 
+	3/11/15
+*/
+
+SCHEMA etude14
+
+ROOT Sender:   (* send *);
+ROOT Receiver: (* receive *);
+
+/* COORDINATE	$x: send FROM Sender, 
+				$y: receive FROM Receiver
+	DO ADD $x PRECEDES $y OD;
+*/

+ 22 - 0
etude15.mp

@@ -0,0 +1,22 @@
+/* advanced test for COORDINATE 
+	3/20/15
+*/
+
+SCHEMA etude15
+
+ROOT Sender:   (* send [ check ] *);
+ROOT Receiver: (* receive confirm *);
+
+COORDINATE	$ch: check FROM Sender, 
+			$con: confirm FROM Receiver
+	DO ADD $ch FOLLOWS $con; OD;
+	
+ROOT Monitor: {* watching *};
+ watching: ( happy | angry );
+
+/* receive happens only when Monitor is happy */
+/* variant 1, example with three coordination threads */
+COORDINATE <!>	$s: send FROM Sender, 
+				$h: happy FROM Monitor,
+				$r2: receive FROM Receiver
+	DO ADD $h FOLLOWS $s, $r2 FOLLOWS $h; OD;

+ 13 - 0
etude16.mp

@@ -0,0 +1,13 @@
+/* basic test for COORDINATE 
+	3/11/15
+*/
+
+SCHEMA etude16
+
+ROOT Sender:   (* send  *);
+ROOT Receiver: (* receive  *);
+
+COORDINATE	$s: send FROM Sender, 
+			$r: receive FROM Receiver
+	DO ADD $r FOLLOWS $s; OD;
+	

+ 37 - 0
etude17.json

@@ -0,0 +1,37 @@
+{"traces":[
+[[["A","R",1],["a1","A",2],["a2","A",3],["a3","A",4],["C","C",5],["c1","A",6],["B","R",7],["b1","A",8],["b3","A",10],["D","R",13],["d","A",14]],
+[[2,1],[3,1],[3,7],[4,1],[5,1],[5,7],[6,5],[8,7],[10,7],[14,13]],
+[[3,2],[3,8],[4,3],[5,4],[5,10],[8,2],[10,3],[14,3]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a3","A",4],["C","C",5],["c1","A",6],["B","R",7],["b1","A",8],["b3","A",10],["D","R",13],["e","A",14]],
+[[2,1],[3,1],[3,7],[4,1],[5,1],[5,7],[6,5],[8,7],[10,7],[14,13]],
+[[3,2],[3,8],[4,3],[5,4],[5,10],[8,2],[10,3],[14,3]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a3","A",4],["C","C",5],["c2","A",6],["B","R",7],["b1","A",8],["b3","A",10],["D","R",13],["d","A",14]],
+[[2,1],[3,1],[3,7],[4,1],[5,1],[5,7],[6,5],[8,7],[10,7],[14,13]],
+[[3,2],[3,8],[4,3],[5,4],[5,10],[8,2],[10,3],[14,3]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a3","A",4],["C","C",5],["c2","A",6],["B","R",7],["b1","A",8],["b3","A",10],["D","R",13],["e","A",14]],
+[[2,1],[3,1],[3,7],[4,1],[5,1],[5,7],[6,5],[8,7],[10,7],[14,13]],
+[[3,2],[3,8],[4,3],[5,4],[5,10],[8,2],[10,3],[14,3]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c1","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["d","A",16],["d","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c1","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["d","A",16],["e","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c1","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["e","A",16],["d","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c1","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["e","A",16],["e","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c2","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["d","A",16],["d","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c2","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["d","A",16],["e","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c2","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["e","A",16],["d","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]],
+[[["A","R",1],["a1","A",2],["a2","A",3],["a2","A",4],["a3","A",5],["C","C",6],["c2","A",7],["B","R",8],["b1","A",9],["b3","A",12],["D","R",15],["e","A",16],["e","A",17]],
+[[2,1],[3,1],[3,8],[4,1],[4,8],[5,1],[6,1],[6,8],[7,6],[9,8],[12,8],[16,15],[17,15]],
+[[3,2],[3,9],[4,3],[5,4],[6,5],[6,12],[9,2],[12,4],[16,3],[17,16],[17,4]]]]}

+ 19 - 0
etude17.mp

@@ -0,0 +1,19 @@
+/* basic test for SHARE ALL 
+	3/22/15
+*/
+SCHEMA etude17
+
+ROOT A: a1 (*<1..2> a2  *) a3 C;
+ROOT B: b1 (*<1..2> a2  *) b3 C;
+
+C: (c1 | c2);
+
+A, B SHARE ALL a2, C;
+
+COORDINATE $x: a1 FROM A, $y: b1 FROM B
+	DO ADD $x PRECEDES $y; OD;
+	
+ROOT D: (*<1..2> (d|e) *);
+COORDINATE $v: a2 FROM A, $w: (d|e) FROM D
+		DO ADD $w FOLLOWS $v; OD;
+	

+ 14 - 0
etude18.mp

@@ -0,0 +1,14 @@
+/* basic test for SHARE ALL 
+	3/22/15
+*/
+
+SCHEMA etude18
+
+ROOT A:  (* a2  *) ;
+ROOT B: (* a2 *) (* b3 *);
+
+A, B SHARE ALL a2;
+	
+ROOT D: (* b3 *);
+
+B, D SHARE ALL b3;

+ 11 - 0
etude19.mp

@@ -0,0 +1,11 @@
+/* basic test for SHARE ALL 
+	3/22/15
+*/
+
+SCHEMA etude19
+
+ROOT A: a b;
+ROOT B: b a;
+
+A, B SHARE ALL a, b;
+	

+ 10 - 0
etude20.json

@@ -0,0 +1,10 @@
+{"traces":[
+[[["A","R",1],["B","R",2],["C","R",3]],
+[],
+[]],
+[[["A","R",1],["a","A",2],["b","A",3],["B","R",4],["C","R",7]],
+[[2,1],[2,4],[2,7],[3,1],[3,4]],
+[[3,2]]],
+[[["A","R",1],["a","A",2],["b","A",3],["a","A",4],["b","A",5],["B","R",6],["C","R",11]],
+[[2,1],[2,6],[2,11],[3,1],[3,6],[4,1],[4,6],[4,11],[5,1],[5,6]],
+[[3,2],[4,3],[4,2],[5,4]]]]}

+ 14 - 0
etude20.mp

@@ -0,0 +1,14 @@
+/* basic test for SHARE ALL 
+	3/25/15
+*/
+
+SCHEMA etude20
+
+ROOT A: (* a b *);
+ROOT B: (* (b|a) (a|b) *);
+
+A, B SHARE ALL a, b;
+
+ROOT C: (* a *);
+
+A, B, C SHARE ALL a;

+ 24 - 0
lexer.mp

@@ -0,0 +1,24 @@
+/* from the ACM TOSEM paper draft 
+ runs for scope 1 and 2, for scope 3 takes too long
+*/
+
+SCHEMA lexer
+
+ROOT Text_Input:  	(* String_processing *);
+	String_processing:	Get_string (+ Unget_char +);
+	Get_string:			(+<2..3> Get_char +);
+
+ROOT Token_processing: 	(* Token_recognition *);
+	Token_recognition: 	{+ RegExpr_Match +}
+				(+ Unget_char +)  Fire_rule;
+ 	RegExpr_Match:		(+ Get_char +);
+ 	Fire_rule: 		[ Put_token ];
+
+COORDINATE 	$t: Token_recognition 	FROM 	Token_processing,
+			$s: String_processing	FROM 	Text_Input
+	DO	
+		$t, $s SHARE ALL Unget_char;
+		
+		COORDINATE <!>    $r: RegExpr_Match      FROM  	$t
+			DO 	$r,  $s 	SHARE ALL    Get_char ; 	OD;
+	OD;

+ 947 - 0
mp2.h

@@ -0,0 +1,947 @@
+/*
+ *  mp2.h
+ *  
+ *  Created by Mike Auguston on 2/2/15.
+ *  recursive descent trace generation
+ *	common declarations and globals
+ *
+ *	last update: 03/26/15
+ */
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <ctime>
+#include <vector>
+#include <map>
+#include <set>
+//#include <algorithm>
+
+using namespace std;
+
+//************************
+//***** Statistics
+//************************
+double storage = 0;		// memory for composite segments
+int total_events = 0;	// total events stored
+
+clock_t gen_start,gen_end;	// for time measurement 
+double	dif;		// for time interval 
+
+//************************
+//***** Globals 
+//************************
+ofstream JSON; // text file for trace visualization
+class Event_producer;
+class Composite_producer;
+
+typedef Event_producer *		Event_producer_ref;
+typedef Composite_producer *	Composite_producer_ref;
+typedef vector <Event_producer_ref> trace_segment;
+
+//***************************************
+//*** these are used for traverse() work
+//***************************************
+trace_segment Stack;
+	// Stack used by producers for trace segment construction via traverse()
+
+// to maintain relations lists
+typedef multimap <int, int> pair_list; 
+	// for storing basic relations IN, FOLLOWS, EQUAL for the segment,
+	// matricies for segments are build from these when needed
+pair_list Follows; // to store FOLLOWS 
+pair_list Inside;  // to store IN 
+pair_list Equals;  // to store Equals (result of MAP or SHARE ALL)
+
+// stack accompanying the Stack 
+vector <int> predecessor;	// to track PRECEDES relation during traverse()
+	// push/pop performed in Composite_producer
+
+//===========================
+// for SET_node traverse()
+//--------------------------------------------------
+// initialized in Composite_producer, similar to predecessor.back()
+// used in SET_node_producer_container
+// replace predecessor when traversing Sets
+
+// heads and tails store for each Set a list 
+//	(branch_begin FOLLOWS node) for heads
+//	(forthcoming_node FOLLOWS end-of-branch-event) for tails 
+// each is a permanent list for Set traverse()
+vector<pair_list> heads;
+vector<pair_list> tails;
+
+void find_and_copy_heads(int branch_start, int my_index);
+void find_and_copy_tails(int first_branch_start, pair_list &destination);
+void copy_from_to(int anchor, pair_list &from_list, pair_list &to_list);
+void copy_and_adjust_from_to(int anchor, int adjusted_node, 
+							 pair_list &from_list, pair_list &to_list);
+bool find_in_heads(int node);
+
+//===================================
+// composite producers infrastructure
+//===================================
+void add_relations_for_leader(); // the subroutine for adding relations for 
+		//the leading event in Atomic_producer or Composite_secondary_producer
+
+//********** main list of composite event, root, and schema producers ******
+//==========================================================================
+map <int, Composite_producer_ref> Composite_address_book;
+// for each composite event/root/schema name contains a plain pointer to the 
+// producer object with the segment list
+
+void show_map(pair_list &x);// for debugging printouts
+
+//****************************
+//	event producer types
+//****************************
+enum Event_type {Atom, Composite_producer_node, Composite_event_instance_node, 
+				Composite_secondary_producer_node, 
+				ROOT_node, Schema_node, OR_node, AND_node, SET_node, Empty_node,
+				Coordinate_op, ShareAll_op };
+		
+string event_type_string[] = {	"Atom",	"Composite_producer_node", 
+								"Composite_event_instance_node",
+								"Composite_secondary_producer_node",
+								"ROOT_node", "Schema_node",
+								"OR_node", "AND_node", "SET_node", 
+								"Empty_node", "Coordinate_op", "ShareAll_op" };
+
+//======= traversal results
+enum Traversal_result {failed, success_and_completed, success_and_ready_for_next};
+string Traversal_result_string[] = {"failed", "success_and_completed", 
+									"success_and_ready_for_next"};
+					   
+//**************************************
+//========= generic classes ============
+//**************************************
+
+//********** Event producers ************
+//***************************************
+class Event_producer{
+public:
+
+	int			name;	// event name
+	Event_type	type;
+	
+	// constructor
+	Event_producer(int n){ 
+		name = n; 
+		type = Atom; // default
+	}
+	
+	virtual Traversal_result traverse()=0; // will be overloaded
+	
+	virtual void hold(){} // redefined for OR_nodes
+	
+	virtual void print_event();	
+};
+//--------------------------------------
+class Atomic_producer: public Event_producer {
+public: 
+	// constructor 
+	Atomic_producer(int n): Event_producer(n){} 
+	
+	Traversal_result traverse(){ 
+		// add relations for new event
+		add_relations_for_leader();
+		Stack.push_back(this);
+
+		return success_and_completed;
+	}
+	
+};// end class Atomic_producer
+
+//-----------------------------------------
+// for empty alternatives in Alt and Optional containers
+// does not leave anything on the trace
+class Empty_producer: public Event_producer {
+public: 
+	// constructor 
+	Empty_producer(int n): Event_producer(n){
+		type = Empty_node;
+	} 
+	
+	Traversal_result traverse(){ 
+		return success_and_completed;
+	}
+	
+};// end class Empty_producer
+
+//-----------------------------------------
+class OR_node_producer_container: public Event_producer{
+public:
+	Event_producer_ref * element; // dynamic array of producer elements
+	int element_count;	// length of the element array
+	int	current_alternative; // the alternative to try, when there is one
+	int previous_alternative; // to hold on the alternative waiting until successors complete
+	
+	// constructor 
+	OR_node_producer_container(int n): Event_producer(n){
+		type = OR_node;
+		current_alternative = 0;
+	} 
+
+	Traversal_result traverse(){ 
+		
+		previous_alternative = current_alternative;
+		Traversal_result  result;
+		bool done = false; // to interrupt the for loop when success is reached
+		// try to find a valid alternative
+		for(int i = current_alternative; (i< element_count) && !done; i++){
+			switch(result = (element[i] -> traverse()) ){
+				case failed:				continue; // try next alternative
+					
+				case success_and_completed:	current_alternative++;
+											done = true;
+											break;
+					
+				case success_and_ready_for_next: done = true; 
+					// retain the current_alternative
+			};
+		}
+		if(result == failed) return failed;
+				
+		return (current_alternative >= element_count)?	
+				(current_alternative = 0, success_and_completed): 
+				success_and_ready_for_next;						
+	}
+	
+	void hold(){ //follower in an AND_node may hold advance to the next alternative 
+				 // because the follower has not yet completed
+
+		current_alternative = previous_alternative;
+		// freez producers in the alternative that will be executed next
+		element[current_alternative]->hold();
+	}
+	
+}; // end OR_node_producer_container class
+
+//-----------------------------------------------------------
+class AND_node_producer_container: public Event_producer{
+	// serves sequence producers
+public:
+	Event_producer_ref * element; // array of producer elements
+	int element_count;	// length of the element array
+	Event_type target_event;// set in the generated subclass constructor
+	int completeness_count; // for harvest() to detect when no more options remain
+
+	// constructor 
+	AND_node_producer_container(int n): Event_producer(n){
+		type = target_event = AND_node;
+	} 
+	
+	Traversal_result traverse(){ 
+		
+		completeness_count = 0;
+		for(int i =0; i< element_count; i++){
+			
+			if(target_event == Schema_node) {
+				// before element[i] -> traverse()
+				predecessor.back() = -1; // block regular ordering
+			}
+			switch(element[i] -> traverse()){
+				case failed:					if(completeness_count == i) 
+													// there are no more options to try
+													// let harvest() to stop calling this traverse() again
+													completeness_count = element_count;
+												return failed; 
+				case success_and_completed:		completeness_count++;
+												break;
+				case success_and_ready_for_next:
+					// hold all previous OR_nodes until element[i] completes
+												for(int j = 0; j<i; j++) 
+													element[j]->hold(); 
+			};
+		}	
+		return (completeness_count == element_count)?	success_and_completed: 
+														success_and_ready_for_next;		
+	}
+	
+	void hold(){
+		// hold all nodes until next element completes
+		for(int j = 0; j < element_count; j++){ 
+			element[j]->hold();
+			}
+	}
+}; // end AND_node_producer_container class
+
+//----------------------------------------------------------------------
+class SET_node_producer_container: public Event_producer{
+	// serves set producers
+public:
+	Event_producer_ref * element;	// array of producer elements
+									// set branches
+	int element_count;	// length of the element array
+	
+	// constructor 
+	SET_node_producer_container(int n): Event_producer(n){
+		type = SET_node;
+	} 
+	
+	Traversal_result traverse(){ 
+		int completeness_count = 0;
+		
+		//========= begin Set traversal ================
+		// prepare heads for set branch traversal
+		//==============================================
+		int last = predecessor.back(); // current predecessor, value stored on the top of stack
+		int first_branch_start = Stack.size();
+		pair_list temp_list; // needed to push empty map to heads, 
+							 // and to store this Set's tails before moving them to global tails
+		set<int> my_tails; // will use in this traverse() and store in tails at the very end
+		
+		
+		int my_index = heads.size(); // position in heads vector
+		heads.push_back(temp_list); // start heads[my_index] with empty, will update in situ
+		
+		// prepare heads for the first branch
+		if(last >= 0){
+			// this Set is not at any branch begin in a parent Set
+			heads[my_index].insert(pair<int, int>(first_branch_start, last) );
+		}
+		// find the earliest parent and copy to heads[my_index] for this branch
+		// this Set is at some branch beginning with a parent Set
+		find_and_copy_heads(first_branch_start, my_index);
+		// if first_branch_start is found in any previous Set tails, copy it to heads[my_index]
+		find_and_copy_tails(first_branch_start, heads[my_index]);
+		
+		//============================
+		// main loop starts here
+		//============================
+		for(int i =0; i< element_count; i++){
+			
+			//=================================
+			// before element[i] -> traverse()
+			//=================================
+			predecessor.back() = -1; // block regular ordering
+			int forthcoming_event = Stack.size();
+			
+			if(forthcoming_event > first_branch_start){
+				// not the first branch beginning, copy and adjust
+				copy_and_adjust_from_to(first_branch_start,	 forthcoming_event, 
+										heads[my_index], heads[my_index]);
+			}
+			
+			// copy tails from children Set and delete them, to prevent siblings from using it
+			for(int k = 0; k < tails.size(); k++){
+				multimap<int, int>:: iterator p = tails[k].find(forthcoming_event);
+				multimap<int, int>:: iterator q = tails[k].upper_bound(forthcoming_event);
+				if(p != tails[k].end()){ // found a tail that should be added to my_tails
+					while(p != q) {
+						my_tails.insert(p->second);
+						p++;
+					}
+					tails[k].clear();// done with this Set
+				}
+			}			
+			//===============
+			// traverse()
+			//===============
+			switch(element[i] -> traverse()){
+				case failed:					return failed; 
+				case success_and_completed:		completeness_count++;
+												break;
+				case success_and_ready_for_next:
+					// hold all previous OR_nodes until element[i] completes
+					for(int j = 0; j<i; j++) 
+						element[j]->hold(); 
+			}
+			//===============================
+			// after element[i] -> traverse()
+			//===============================
+			int next_event = Stack.size();
+			if( next_event > forthcoming_event ){
+				// there was a non-empty contribution by traverse()
+				
+				// forthcoming_event exists, now can forward heads[my_index]
+				// for forthcoming_event to Follows
+				// and perform this delayed action
+				copy_from_to(forthcoming_event, heads[my_index], Follows);
+				
+				if(predecessor.back() >= 0){
+					my_tails.insert(predecessor.back());
+				}
+				
+				if(i == element_count - 1){// if the last element, do it now
+					// copy tails from children Set
+					for(int k = 0; k < tails.size(); k++){
+						multimap<int, int>:: iterator p = tails[k].find(next_event);
+						multimap<int, int>:: iterator q = tails[k].upper_bound(next_event);
+						if(p != tails[k].end()){ // found a tail that should be added to my_tails
+							while(p != q) {
+								my_tails.insert(p->second);
+								p++;
+							}
+						tails[k].clear();// done with this Set
+						}
+					}
+				}
+			}
+			// else continue element[i+1] -> traverse() with the same heads and tails
+		} // end main loop
+		
+		//============================
+		// end of Set generation
+		//============================		
+		
+		// store tails accumulated in my_tails
+		int next = Stack.size();
+		for(set<int>:: iterator tt = my_tails.begin(); tt != my_tails.end(); tt++){
+			temp_list.insert(pair<int, int>(next, *tt) );
+		}						
+		// finally add to the global tails
+		tails.push_back(temp_list);
+		
+		predecessor.back() = -1; // block regular ordering
+
+		return (completeness_count == element_count)?	success_and_completed: 
+														success_and_ready_for_next;		
+	}
+	
+	void hold(){
+		// hold all nodes until next element completes
+		for(int j = 0; j < element_count; j++){ 
+			element[j]->hold();
+		}
+	}
+	
+}; // end SET_node_producer_container class
+
+//--------------------------------------------------
+// this element sits on the generated event trace, along with Atomic_producers
+// generated in the Composite_secondary_producer, 
+// added at the beginning of each segment,
+// brought from the Composite_producer segments storage
+class Composite_event_instance: public Event_producer{
+public:
+	int index; // fetched segment's index in the segment_storage (version of this composite event)
+	
+	// constructor
+	Composite_event_instance(int n, int indx): Event_producer(n){
+		type	= Composite_event_instance_node;
+		index	= indx;
+	}
+	
+	void print_event();	// defined in the generated part, 
+						// because it needs event type and name strings
+	
+	// to prevent this class from being abstract, as Event_producer
+	Traversal_result traverse(){return success_and_completed;}
+	
+}; // end Composite_event_instance class
+
+//---------------------------------------------------------------
+// is a subclass of generated Composite classes
+// this object creates and stores list of composite event instances
+// traverse() is called from its harvest() only
+class Composite_producer: public AND_node_producer_container {
+public:
+	// storage for secondary producers
+	//===================================
+	vector <trace_segment> segments;// composite event trace instance list
+	// to store relation lists for the segments
+	vector <pair_list>	follows_lists; // to store FOLLOWS 
+	vector <pair_list>  inside_lists;  // to store IN 
+	vector <pair_list>  equals_lists;  // to store Equals (results of MAP or SHARE ALL)
+	
+	// constructor
+	Composite_producer(int n): AND_node_producer_container(n){
+		type = Composite_producer_node;
+		// posts a reference to itself on the Composite_address_book
+		Composite_address_book.insert(pair<int, Composite_producer_ref>(name, this));
+	}
+	
+	Traversal_result traverse(){ 
+		// creates a single trace on the Stack
+		return this -> AND_node_producer_container::traverse();
+	}
+		
+	// calls traverse to fill the segments list
+	void harvest();		// defined in mp2_print_etc.h
+	
+	void show_traces(); // defined in mp2_print_etc.h
+	
+	void output_JSON(); // defined in mp2_print_etc.h
+	
+}; // end Composite_producer class
+
+//-------------------------------------------------------
+// sits in the recursive descent graph
+// used during the recursive descent to traverse composite storage 
+// and to fetch the next composite segment
+// previous_index shows the position of segment added to the trace
+class Composite_secondary_producer: public Event_producer{
+public:
+	Composite_producer_ref segment_storage;// ptr to segment info stored in Composite_producer
+	int index; // segment info index in the segment_storage to fetch now
+	int previous_index; // for hold() implementation
+	
+	// constructor
+	Composite_secondary_producer(int n): Event_producer(n){
+		type = Composite_secondary_producer_node;
+		
+		// find segment list storage
+		map <int, Composite_producer_ref> :: iterator p;
+		p = Composite_address_book.find(name);
+		if(p == Composite_address_book.end()){
+			cout<< "Composite_secondary_producer constructor cannot find segment storage for the\n";
+			print_event();
+			segment_storage = NULL;
+		}
+		else segment_storage = p-> second;
+		index = 0;
+		previous_index = 0;
+	}
+	
+	Traversal_result traverse(){
+		if(!segment_storage) {
+			// add relations for new event and add it
+			add_relations_for_leader();
+			Stack.push_back(new Composite_event_instance(name, 0));
+			return success_and_completed;
+		}
+		
+		// we are going to fetch this segment from the storage
+		trace_segment * my_segment_ptr = & ((segment_storage->segments)[index]);
+					
+		// prepare for added segement scanning for relation update
+		int base = Stack.size(); //master Composite_event_instance event's position in the trace
+		// base is the position of composite event inside which the segment belongs
+
+		// fetch a valid alternative and adjust relation list
+		add_relations_for_leader();// add IN/PRECEDES for the composite event at the beginning of segment
+		Stack.insert(Stack.end(), my_segment_ptr->begin(), my_segment_ptr->end() );
+						
+		// get the relation lists from the storage, adjust them with base, 
+		// and add to Follows, Inside and Equals
+		multimap <int, int>:: iterator p;
+		pair_list * my_rel_list_ptr = & ((segment_storage->follows_lists)[index]);
+		
+		for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
+			// scan the list of pairs and add them to Follows adjusted with base
+			Follows.insert(pair<int, int>( (p->first)	+ base,
+										   (p->second)	+ base ) );
+		}
+		
+		my_rel_list_ptr = & ((segment_storage->inside_lists)[index]);
+		for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
+			// scan the list of pairs and add them to Follows adjusted with base
+			Inside.insert(pair<int, int>(	(p->first)	+ base,
+											(p->second)	+ base ) );
+		}
+		
+		my_rel_list_ptr = & ((segment_storage->equals_lists)[index]);
+		for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
+			// scan the list of pairs and add them to Follows adjusted with base
+			Equals.insert(pair<int, int>(	(p->first)	+ base,
+											(p->second)	+ base ) );
+		}
+		previous_index = index;
+		index++;
+				
+		return (index >= (segment_storage->segments).size() )?	
+							(index = 0, success_and_completed): 
+							success_and_ready_for_next;						
+	}
+	
+	void hold(){ 
+		//follower in an AND_node may hold advance to the next alternative 
+		// because the follower has not yet completed
+		index = previous_index;
+		}
+	
+}; // end Composite_secondary_producer class
+//---------------------------------------------------------------------------
+
+class Coordinate: public Event_producer {
+public:
+	// these arrays are 2-dimensional, 
+	// and are allocated/deleted in generated traverse()
+	// by create_matrices() as Stack.size() * Stack.size()
+	char * eq_matrix;
+	char * in_matrix;
+	char * follows_matrix;
+	int len; // matrix dimension
+	int matrix_len; // len * len
+	
+	// constructor
+	Coordinate(int n): Event_producer(n){
+		type = Coordinate_op;
+		eq_matrix = in_matrix = follows_matrix = 0;
+		len = matrix_len = 0;
+	} 
+	
+	// transitive closures are based on Floyd-Warshall algorithm 
+	// [Cormen et al. 3rd Edition,  pp.699]
+	//--------------------------------------------------------------
+	void eq_transitive_closure(char * m){
+		for(int k = 0; k < len; k++){
+			for(int i = 0; i < len; i++){
+				for(int j = 0; j < len; j++){
+					m[i * len + j] = 
+						m[i * len + j] || (m[i * len + k] && m[k * len + j]);
+				}
+			}
+		}
+	} // end eq_transitive_closure(char * m)
+	
+	void in_transitive_closure(char * m){
+		// merge equal event rows
+		for(int i = 0; i < len; i++){
+			for(int j = 0; j < len; j++){
+				if(eq_matrix[i * len + j] && (i != j)){
+					for(int k = 0; k < len; k++){
+						m[i * len + k] = 
+						m[j * len + k] =
+							m[i * len + k] || m[j * len + k];
+					}
+				}
+			}
+		}
+		// do the closure
+		for(int k = 0; k < len; k++){
+			for(int i = 0; i < len; i++){
+				for(int j = 0; j < len; j++){
+					m[i * len + j] = 
+					m[i * len + j] || (m[i * len + k] && m[k * len + j]);
+				}
+			}
+		}
+		// check for loops: axioms 5-6
+		for(int i = 0; i < len; i++){
+			if(m[i * len + i]) throw failed;
+		}
+	} // end in_transitive_closure(char * m)
+	
+	void fw_transitive_closure(char * m){
+		// merge equal event rows
+		for(int i = 0; i < len; i++){
+			for(int j = 0; j < len; j++){
+				if(eq_matrix[i * len + j] && (i != j)){
+					for(int k = 0; k < len; k++){
+						m[i * len + k] = 
+						m[j * len + k] =
+						m[i * len + k] || m[j * len + k];
+					}
+				}
+			}
+		}
+		// propagate FOLLOWS to the inner events
+		for(int i = 0; i < len; i++){
+			for(int j = 0; j < len; j++){
+				// distributivity axioms 9-10
+				if(in_matrix[i * len + j]){
+					for(int k = 0; k < len; k++){
+						m[k * len + i] = 
+						m[k * len + i] || m[k * len + j];
+					}
+					for(int k = 0; k < len; k++){
+						m[i * len + k] = 
+						m[i * len + k] || m[j * len + k];
+					}
+				}
+			}
+		}
+		// do the closure
+		for(int k = 0; k < len; k++){
+			for(int i = 0; i < len; i++){
+				for(int j = 0; j < len; j++){
+					m[i * len + j] = 
+					m[i * len + j] || (m[i * len + k] && m[k * len + j]);
+				}
+			}
+		}
+		// check for loops: axioms 5-6
+		for(int i = 0; i < len; i++){
+			if(m[i * len + i]) throw failed;
+		}
+		// check for mutual exclusion: axioms 1-4
+		for(int k = 0; k < len; k++){
+			for(int i = 0; i < len; i++){
+				if(in_matrix[k * len + i] && 
+				   follows_matrix[k * len + i]) throw failed; 
+			}
+		}
+	} // end fw_transitive_closure(char * m)
+
+	void delete_matrices(){
+		if(in_matrix){
+			delete [] eq_matrix;
+			delete [] in_matrix;
+			delete [] follows_matrix;
+			eq_matrix = in_matrix = follows_matrix = 0;
+		}
+	}
+	
+	void create_matrices(){
+		len =			Stack.size();
+		matrix_len =	len * len;
+		
+		// allocate and initialize with 0
+		eq_matrix =			new char [matrix_len];
+		in_matrix =			new char [matrix_len];
+		follows_matrix =	new char [matrix_len];
+		for(int i = 0; i < matrix_len; i++){
+			eq_matrix[i] =		
+			in_matrix[i] =		
+			follows_matrix[i] = 0;
+		}
+		
+		multimap <int, int>:: iterator p;
+		
+		// fill eq matrix
+		for(p = Equals.begin(); p != Equals.end(); p++){
+			eq_matrix[p->first * len + p->second ] = 
+			eq_matrix[p->second * len + p->first ] = 1;
+		}
+		eq_transitive_closure(eq_matrix);
+		
+		// fill in matrix
+		for(p = Inside.begin(); p != Inside.end(); p++){
+			in_matrix[p->first * len + p->second ] = 1;
+		}
+		in_transitive_closure(in_matrix);
+		
+		// fill follows matrix
+		for(p = Follows.begin(); p != Follows.end(); p++){
+			follows_matrix[p->first * len + p->second ] = 1;
+		}		
+		fw_transitive_closure(follows_matrix);
+		
+	} // end create_matrices()
+		
+	void sort_events(vector<int> &L){
+		// sorts vector of events by FOLLOWS
+		// Selection Sort, Levitin p.99 (OK for small lists)
+		// since FOLLOWS is partial order, the sort is topological
+		// although selection sort is not stable
+		if(L.size() < 2) return;
+		int min, temp;
+
+		for(int i = 0; i < L.size() - 1; i++){
+			min = i;
+			for(int j = i + 1; j < L.size(); j++){
+				if(follows_matrix[L[min] * len + L[j]]){
+					min = j;
+				}
+			}
+			temp = L[i];
+			L[i] = L[min];
+			L[min] = temp;
+		}		
+	}
+	
+	void sort_and_check_coordinated_events(vector<int> &L){
+		// for synchronous COORDINATE
+		// sorts vector of events by FOLLOWS
+		// then checks for total ordering
+		if(L.size() < 2) return;
+		sort_events(L);
+		
+		// check total ordering
+		for(int i = 0; i < L.size() - 1; i++){
+			if(!follows_matrix[L[i + 1] * len + L[i]]) throw failed;
+		}		
+	}
+	
+	void make_equality_complete(int a, int b){
+		// add to Equals, but earlier position in Stack is more equal :-)
+		// copies all Follows and Inside from b to a
+		// and do the same for all inner events
+		if(a == b) return;
+		if(Stack[a]->name != Stack[b]->name) throw failed;
+		if(Stack[a]->type == Composite_event_instance_node && 
+		   Stack[b]->type == Composite_event_instance_node &&
+		   ( ((Composite_event_instance *)Stack[a])->index != 
+			 ((Composite_event_instance *)Stack[b])->index ) )throw failed;		
+		
+		// earlier position in Stack is more equal :-)
+		if(a > b) {int t = a; a = b; b = t;}
+		Equals.insert(pair<int, int>(a, b));
+		// copy all Follows and Inside from b to a
+		multimap<int, int>:: iterator p;
+		
+		for(p = Follows.begin(); p != Follows.end(); p++) {
+			if(p->second == b)
+				Follows.insert(pair<int, int>(p->first, a));
+			if(p->first == b)
+				Follows.insert(pair<int, int>(a, p->second));		
+		}
+		
+		for(p = Inside.begin(); p != Inside.end(); p++) {
+			if(p->first == b)
+				Inside.insert(pair<int, int>(a, p->second));
+		}
+
+		if(Stack[a]->type == Atom) return;
+		
+		// if composite event, do the same for all inner events
+		vector<int> a_list, b_list;
+		
+		p = Inside.begin();
+		while(p != Inside.end()) {
+			if(p->second == a) a_list.push_back(p->first);
+			if(p->second == b) b_list.push_back(p->first);
+			p++;
+		}
+		if(a_list.size() != b_list.size()) throw failed;
+		sort_events(a_list);
+		sort_events(b_list);
+		for(int i = 0; i < a_list.size() && i < b_list.size(); i++){
+			make_equality_complete(a_list[i], b_list[i]);
+		}		
+	}// end make_equality_complete()
+	
+	void print_matrix(char * m){
+		cout<<" size: "<<len<< " * "<<len<<endl;
+		cout<< " \t";
+		for(int k = 0; k < len; k++){
+			cout<<k<<" \t";
+		}
+		for(int i= 0; i < len; i++){
+			cout<<"\n"<<i<<": \t";
+			for(int j = 0; j <len; j++){
+				cout<<(int)m[i * len + j]<<" \t";
+			}
+		}
+	}
+	
+	void print_matrices(){
+		cout<<"\n\neq_matrix ";
+		print_matrix(eq_matrix);
+		cout<<"\n\nin_matrix ";
+		print_matrix(in_matrix);
+		cout<<"\n\nfollows_matrix ";
+		print_matrix(follows_matrix);
+	}
+	
+	// traverse() is defined in the generated subclasses
+	
+}; // end Coordinate class
+
+//========== auxiliary subroutines and declarations =========================
+
+inline void add_relations_for_leader(){
+// add relations for the event which will be in a moment pushed on the top of Stack
+// called from Atomic_producer or Composite_secondary_producer
+// when they add to the trace
+	
+	int myindex = Stack.size(); // index of this event in the segment,
+								// before the event is actually pushed on the stack
+	
+	// always inside the master composite of the segment
+	// will be further adjusted in Composite_secondary_producer traverse()
+	Inside.insert(pair<int, int>(myindex, 0));
+
+	// add PRECEDES according to the position in AND_node_producer_container where it belongs
+	int last = predecessor.back(); // value stored on the top of stack
+	if(last >= 0) { // if predecessor is defined
+		Follows.insert(pair<int, int>(myindex, last) );
+	}
+	else{// happens seldom, only inside Set, or at the beginning of Composite
+		// if heads have this node, do nothing, it will be taken care in Set, 
+		// otherwise, if tails have this node, add it to Follows
+		if( !find_in_heads(myindex)) find_and_copy_tails(myindex, Follows);
+	}
+	predecessor.back() = myindex; // place this event as a previous
+}
+
+//---------------------------------------------------------------------------
+inline void copy_from_to(int anchor, pair_list &from_list, pair_list &to_list){
+	// called from SET_node_producer_container.traverse()
+	multimap<int, int>:: iterator q = from_list.find(anchor);
+	if(q != from_list.end()){
+		do {
+			to_list.insert(pair<int, int>(anchor, q->second) );
+			q++;
+		} while ( q != from_list.upper_bound(anchor));
+	}
+}
+//----------------------------------------------------------------------------
+inline void copy_and_adjust_from_to(int anchor, int adjusted_node, 
+									pair_list &from_list, pair_list &to_list){
+	// called from SET_node_producer_container.traverse()
+
+	multimap<int, int>:: iterator p = from_list.find(anchor);
+	multimap<int, int>:: iterator q = from_list.upper_bound(anchor);					
+	if(p != from_list.end()) {
+		set<int> temp;
+		// collect all predecessors of anchor in from_list
+		do {
+			temp.insert( p->second);
+			p++;
+		} while ( p != q );
+		// put them into to_list for adjusted_node
+		for(set<int>:: iterator tt = temp.begin(); tt != temp.end(); tt++){
+			to_list.insert(pair<int, int>(adjusted_node, *tt) );
+		}						
+	}	
+}
+//-----------------------------------------------------------------------------
+void find_and_copy_heads(int branch_start, int my_index){
+	// called from SET_node_producer_container.traverse()
+	// find the first parent Set that contains branch_start
+	// and copy all branch_start -> N to heads[my_index]
+	for(int i = 0; i < my_index; i++){
+		multimap<int, int>:: iterator p = heads[i].find(branch_start);
+		multimap<int, int>:: iterator q = heads[i].upper_bound(branch_start);
+		if(p != heads[i].end()){ // found a parent Set
+			while(p != q) {
+				heads[my_index].insert(pair<int, int>(branch_start, p->second) );
+				p++;
+			}
+			return;
+		}	
+	}
+}
+//-------------------------------------------------------------------------------
+void find_and_copy_tails(int node, pair_list &destination){
+	// called from SET_node_producer_container.traverse() and add_relations_for_leader()
+	// if node is found in any previous Set tails, copy it to destination
+	for(int i = 0; i < tails.size(); i++){
+		multimap<int, int>:: iterator p = tails[i].find(node);
+		multimap<int, int>:: iterator q = tails[i].upper_bound(node);
+		if(p != tails[i].end()){ // found a match
+			while(p != q) {
+				destination.insert(pair<int, int>(node, p->second) );
+				p++;
+			}
+			// now can discard it
+			tails[i].clear();
+		}	
+	}
+	return;	
+}
+//--------------------------------------------------------------------------------
+bool find_in_heads(int node){
+	// called from add_relations_for_leader()
+	for(int i = 0; i < heads.size(); i++){
+		multimap<int, int>:: iterator p = heads[i].find(node);
+		if(p != heads[i].end())  return true;// found a match
+	}
+	return false;		
+}
+//=======================================================================================
+void show_statistics(){
+	/*
+	cout<<"\n*** Statistics **************************************\n";
+	cout<<"size of Event_producer = "<< sizeof(Event_producer)<<endl;
+	cout<<"size of OR_node_producer_container = "<< sizeof(OR_node_producer_container)<<endl;
+	cout<<"size of AND_node_producer_container = "<< sizeof(AND_node_producer_container)<<endl;
+	cout<<"size of SET_node_producer_container = "<< sizeof(SET_node_producer_container)<<endl;
+	cout<<"size of Composite_producer = "<< sizeof(Composite_producer)<<endl;
+	cout<<"size of Composite_secondary_producer = "<< sizeof(Composite_secondary_producer)<<endl;
+	cout<<"size of Coordinate = "<< sizeof(Coordinate)<<endl;
+	cout<<"   *** These are stored on the trace\n";
+	cout<<"size of Atomic_producer = "<< sizeof(Atomic_producer)<<endl;
+	cout<<"size of Composite_event_instance = "<< sizeof(Composite_event_instance)<<endl;
+	 */
+	cout<<"\ntotal number of stored events= "<< total_events;
+	cout<< "\nmemory of composite storage= "<< storage  << " bytes/ "<<
+	(double)storage /1024<< "KB/ "<< (double)storage /1024/1024<< "MB (JEDEC binary definition)"<<endl;
+	
+	//gen_end = clock(); 
+	dif = double(gen_end - gen_start) / CLOCKS_PER_SEC;
+	cout<<"Elapsed time "<< dif<<" sec, Speed: "<<  total_events/dif  <<" events/sec\n"<<endl; 
+		
+}

+ 244 - 0
mp2_print_etc.h

@@ -0,0 +1,244 @@
+/*
+ *  mp2_print_subroutines.h
+ *
+ *  Created by Mike Auguston on 02/05/15.
+ *	last modified 03/22/15
+ */
+//=======================================
+// this declaration uses Event_name enum
+// it is a single object referred when needed by containers
+// does not leave anything on the trace
+Empty_producer Dummy(Dummy_event);
+
+//=======================================
+// print uses event_name_string[]
+//-----------------------------------------
+void Composite_producer::harvest(){
+	// calls traverse to fill the segments list
+
+	Traversal_result  result;
+	int my_total =	0;
+	int min_trace = 10000000;
+	int max_trace = 0;
+
+	do {
+		// reset Stack and relation lists to start new trace assembly 
+		Stack.clear();
+		Follows.clear();
+		Inside.clear();
+		Equals.clear();
+		tails.clear();
+		heads.clear();
+		
+		// prepare stacks for traversal
+		predecessor.clear();
+		predecessor.push_back(-1);
+		// no predecessor for the event at beginning of a segment
+		// it will be brought by containers in add_relations_for_leader()
+		
+		// add a Composite event instance event to the trace: name, index, and length
+		// the length of segment will be adjusted later
+		Stack.push_back(new Composite_event_instance(name, segments.size()));	
+		Stack[0]->type = target_event;
+		result = traverse(); // fills the Stack and relation lists
+		// relations are assembled/processed in the container objects
+		
+		predecessor.pop_back(); // restore ordering for the previous nesting level
+		
+		if(result == failed){
+			if(completeness_count == element_count) break;
+								// there are no more options to try
+			else continue;
+		}
+		
+		// store the assembled segment, its relation lists and event stats
+		segments.push_back(Stack);
+		follows_lists.push_back(Follows);
+		inside_lists.push_back(Inside);
+		equals_lists.push_back(Equals);
+		
+		// do statistics: for total number of events stored <<<<<<<<<<<<
+		int segment_len = Stack.size();
+		total_events += segment_len;
+		my_total += segment_len;
+		if(segment_len < min_trace) min_trace = segment_len;
+		if(segment_len > max_trace) max_trace = segment_len;
+		storage += (sizeof Stack) + sizeof(Event_producer_ref) * segment_len + 
+		3 * sizeof(pair_list) + 
+		sizeof (pair<int, int>) * (Follows.size() + Inside.size() + Equals.size());
+				
+	} while(result != success_and_completed);
+	
+	if(segments.size())
+		cout<<"completed "<<event_name_string[name]<<": \t"<<segments.size()<<" traces \t"<<
+			my_total<<" events \n\t\taverage "<<(double)my_total/segments.size()<< 
+			" ev/trace \tmin "<< min_trace<< " \tmax "<<max_trace<<endl<<endl;
+	else cout<<"no traces found for "<<event_name_string[name]<<endl;
+	
+}// end harvest()
+
+//-----------------------------------------------------
+
+void Event_producer::print_event(){
+	cout<< " Event " << event_name_string[name] << " \ttype= " << event_type_string[type] 
+	<<endl;
+}
+
+void Composite_event_instance::print_event(){
+	cout<< " Event " << event_name_string[name] << " \ttype= " << event_type_string[type] << 
+	" index= "<< index<< endl;
+}
+
+//------------- debugging print subroutines -----------------
+void show_map(pair_list &x){
+	for(multimap<int, int>:: iterator q = x.begin(); q != x.end(); q++){
+		cout<<" ("<< q->first<<", "<<q->second<<")\n";
+	}
+	
+}
+//----------------------------------------------------------
+void Composite_producer::show_traces(){
+	cout<< "\nTotal "<< segments.size()<< " traces for Composite "<< event_name_string[name] << endl; 
+	cout<<"=========================\n";
+	for(int k =0; k < segments.size(); k++){
+		cout<< "trace #"<< k+1 <<" with " << segments[k].size() << " events\n";
+		for(int i = 0; i < segments[k].size(); i++){
+			cout<<'('<< i << ") ";
+			segments[k][i] ->print_event();
+		}
+		
+		multimap <int, int>:: iterator p;
+		cout<<"\n FOLLOWS list for trace #"<< k+1<<endl;
+		for(p = follows_lists[k].begin(); p != follows_lists[k].end(); p++){
+			cout<< "   "<< p->first<< " follows "<< p->second<<endl;
+		}
+		
+		cout<<"\n IN list for trace #"<< k+1<<endl;
+		for(p = inside_lists[k].begin(); p != inside_lists[k].end(); p++){
+			cout<< "   "<< p->first<< " inside "<< p->second<<endl;
+		}
+		
+		cout<<"\n EQUALS list for trace #"<< k+1<<endl;
+		for(p = equals_lists[k].begin(); p != equals_lists[k].end(); p++){
+			cout<< "   "<< p->first<< " equals "<< p->second<<endl;
+		}
+		
+		cout<<endl;
+	}
+}
+//-----------------------------------------------------------
+void Composite_producer::output_JSON(){
+	string comma, comma2;
+	JSON<< "{\"traces\":[" << endl;
+	comma2 = "";
+	for(int kk =0; kk < segments.size(); kk++){
+		JSON<< comma2;
+		comma2 = ",\n";
+		JSON<< "[[";	// start trace and event list
+		
+		// in preparation for equality cleaning
+		int len = segments[kk].size();
+		int matrix_len = len * len;
+		char eq_matrx[matrix_len];
+		char invalid[len]; // list of invalidated events
+
+		for(int j = 0; j < matrix_len; j++){
+			eq_matrx[j] = 0;
+		}
+		for(int j = 0; j < len; j++){
+			invalid[j] = 0;
+		}
+		invalid[0] = 1;// invalidate the main schema event
+		
+		multimap <int, int>:: iterator p;
+		multimap <int, int>:: iterator q = equals_lists[kk].end();
+
+		// fill eq_matrx
+		for(p = equals_lists[kk].begin(); p != q; p++){
+			eq_matrx[p->first * len + p->second ] = 
+			eq_matrx[p->second * len + p->first ] = 1;
+		}
+		
+		// transitive closure is based on Floyd-Warshall algorithm 
+		// [Cormen et al. 3rd Edition,  pp.699]
+		//--------------------------------------------------------------
+		for(int t = 0; t < len; t++){
+			for(int i = 0; i < len; i++){
+				for(int j = 0; j < len; j++){
+					eq_matrx[i * len + j] = 
+						eq_matrx[i * len + j] || 
+						(eq_matrx[i * len + t] && eq_matrx[t * len + j]);
+				}
+			}
+		}
+		
+		// fill the list of invalidated events
+		// all but earliest equal are marked by 1
+		for(int k = 1; k < len; k++){
+			if(invalid[k]) continue;
+			for(int i = 1; i < len; i++){
+				if(eq_matrx[k * len + i] && k != i){					
+					invalid[i] = 1;
+				}
+			}
+		}
+		
+		// print event list
+		comma = "";
+		for(int i = 1; i < len; i++){
+			if(!invalid[i]){
+				JSON<< comma;
+				comma = ",";
+				JSON<<"[\""<<		// start event pair
+					event_name_string[segments[kk][i] ->name]<<"\",\"";
+				switch(segments[kk][i] ->type){
+					case Composite_event_instance_node: 
+						JSON<<'C'; break;
+					case Atom: 
+						JSON<<'A'; break;
+					case ROOT_node: 
+						JSON<<'R'; break;
+					case Schema_node: 
+						JSON<<'S'; break;
+					default: JSON<< "unknown event type: "<< segments[kk][i] ->type;
+				}
+				JSON<<"\","<<i<<"]"; // end event pair
+			}
+		}
+		JSON<<"],\n["; // end event list and start inside list
+		
+		// print IN relations
+		int prev_first, prev_second; // to avoid duplications
+		comma = "";
+		prev_first = prev_second = -1;
+		for(p = inside_lists[kk].begin(); p != inside_lists[kk].end(); p++){
+			if(!invalid[p->first] && !invalid[p->second] && 
+			   !(p->first == prev_first && p->second == prev_second)){ 
+				JSON<< comma;
+				comma = ",";
+				JSON<< "["<< p->first<< ","<< p->second<<"]";
+				prev_first = p->first;
+				prev_second = p->second;
+			}
+		}
+		JSON<<"],\n[";	// end inside list and start follows list
+		
+		// print FOLLOWS relations
+		comma = "";
+		prev_first = prev_second = -1;
+		for(p = follows_lists[kk].begin(); p != follows_lists[kk].end(); p++){
+			if(!invalid[p->first] && !invalid[p->second] && 
+			   !(p->first == prev_first && p->second == prev_second)){
+				JSON<< comma;
+				comma = ",";
+				JSON<< "["<< p->first<< ","<< p->second<<"]";
+				prev_first = p->first;
+				prev_second = p->second;
+			}
+		}
+		JSON<<"]]";	// end follows list and trace
+	}
+	JSON<<"]}"<<endl;
+}
+
+

+ 14 - 0
rall

@@ -0,0 +1,14 @@
+#!/bin/csh -f
+# $1 - schema name, $2 - scope
+set rig='~/rigal/rigsc.446/bin'
+$rig/rc MP2-parser
+$rig/ic MP2-parser -d $1 tree $2> temp.txt
+$rig/rc MP2-generator
+$rig/ic MP2-generator -d tree> temp2.txt
+rm tree *.rsc
+echo "C++ compiler: g++ $1.cpp -o $1 -fast"
+time /Developer/usr/bin/g++ "$1.cpp" -o $1 -fast
+echo "$1 run: ./$1>$1.txt"
+time ./$1>"$1.txt"
+echo "Completed $1 for scope $2"
+rm $1 xd RIGCOMP.TMP