------------------------------------------------------------------------------ -- Cheddar is a free real time scheduling tool. -- This program provides services to automatically check temporal constraints -- of real time tasks. -- -- Copyright (C) 2002-2009 Frank Singhoff -- Cheddar is developed by the LISYC Team, University of Brest -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- -- Contact : cheddar@listes.univ-brest.fr -- To post to this mailing list, you must be subscribed -- (see http//beru.univ-brest.fr/~singhoff/cheddar for details) -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Generic_Graph; use Generic_Graph; use Generic_Graph.Edge_Lists_Package; use Generic_Graph.Node_Lists_Package; with DP_Graph; use DP_Graph; with DP_Graph.extended; use DP_Graph.extended; with Tasks; use Tasks; with Buffers; use Buffers; with Messages; use Messages; with Dependencies; use Dependencies; with Resources; use Resources; with Systems; use Systems; with Processors; use Processors; with Convert_Strings; with Convert_Unbounded_Strings; with Text_IO; use Text_IO; with Ada.Finalization; with Unbounded_Strings; use Unbounded_Strings; use Unbounded_Strings.Unbounded_String_List_Package; with Debug; use Debug; with Unchecked_Deallocation; package body DP_Graph_view is --Views based on Dependency types -- function Time_Triggered_Communication_View (obj : in Graph) return Graph is res : Graph; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; succeed : Boolean; temporary_task_node : Task_Node_Ptr; begin Initialize (res); Initialize (temporary_task_node); Reset_Head_Iterator (obj.Edges, E_Iterator); if not Is_Empty (obj.Edges) then Current_Element (obj.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (obj.Edges, E_Iterator)) loop if Element_In_List (To_Unbounded_String ("DP_GRAPH.Time_Triggered_Communication_EDGE"), type_of (current_edge)) then Add_Generic_Edge (res, Copy (current_edge), succeed); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_1) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_2) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; end if; Next_Element (obj.Edges, E_Iterator); Current_Element (obj.Edges, current_edge, E_Iterator); end loop; if Element_In_List (To_Unbounded_String ("DP_GRAPH.Time_Triggered_Communication_EDGE"), type_of (current_edge)) then Add_Generic_Edge (res, Copy (current_edge), succeed); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_1) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_2) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; end if; end if; return res; end Time_Triggered_Communication_View; function Resource_View (obj : in Graph) return Graph is res : Graph; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; succeed : Boolean; temporary_task_node : Task_Node_Ptr; begin Initialize (res); Initialize (temporary_task_node); Reset_Head_Iterator (obj.Edges, E_Iterator); if not Is_Empty (obj.Edges) then Current_Element (obj.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (obj.Edges, E_Iterator)) loop if Element_In_List (To_Unbounded_String ("DP_GRAPH.RESOURCE_EDGE"), type_of (current_edge)) then Add_Generic_Edge (res, Copy (current_edge), succeed); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_1) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_2) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; end if; Next_Element (obj.Edges, E_Iterator); Current_Element (obj.Edges, current_edge, E_Iterator); end loop; if Element_In_List (To_Unbounded_String ("DP_GRAPH.RESOURCE_EDGE"), type_of (current_edge)) then Add_Generic_Edge (res, Copy (current_edge), succeed); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_1) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed, temporary_task_node); if succeed then if not task_node_in_graph (res, current_edge.all.Node_2) then Add_Node (res, Copy (Task_Node_Ptr (temporary_task_node)), succeed); end if; else raise Undetected_Graph_Construction_Error_Exception; end if; end if; end if; return res; end Resource_View; function Communication_View (obj : in Graph) return Graph is begin return obj; end Communication_View; --View of Graph connex components -- function Connexity_View (obj : in Graph) return Graph_List is res : Graph_List; G_Iterator : Graph_List_Iterator; current_graph : Graph_Ptr; temp_connex_graph : Graph_Ptr; succeed_source : Boolean; succeed_sink : Boolean; succeed_add : Boolean; connex : Boolean; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; current_node_source : Task_Node_Ptr; current_node_sink : Task_Node_Ptr; begin put_line(""); put_line(""); put_debug("Connexity view"); put_debug(To_Unbounded_String ("Nodes: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.nodes)'IMG)); put_debug(To_Unbounded_String ("Edges: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.edges)'IMG)); put_line(""); put_line(""); Initialize (res); Put_Debug ("Tag1"); Reset_Head_Iterator (obj.Edges, E_Iterator); if not Is_Empty (obj.Edges) then Current_Element (obj.Edges, current_edge, E_Iterator); connex := False; Put_Debug ("Tag2"); -- Browsing Graph's Edges while (not Is_Tail_Element (obj.Edges, E_Iterator)) loop -- Put_Debug ("Tag2bis"); Reset_Head_Iterator (res, G_Iterator); Put_Debug ("Tag2ter"); -- begin res not empty if not Is_Empty (res) then Put_Debug ("Tag3"); Current_Element (res, current_graph, G_Iterator); connex := False; --Browsing Connex instances while (not Is_Tail_Element (res, G_Iterator)) loop get_task_node_by_task_name (current_graph, current_edge.all.Node_1, succeed_source, current_node_source); get_task_node_by_task_name (current_graph, current_edge.all.Node_2, succeed_sink, current_node_sink); -- not connex : adding edge if (succeed_source or succeed_sink) and not connex then Add_Generic_Edge (current_graph, current_edge, succeed_add); Put_Debug ("Tag4"); connex := True; temp_connex_graph := current_graph; -- connex : adding node 1 if necessary if not succeed_source then get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Put_Debug ("Tag5"); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); end if; -- connex : adding node 2 if necessary if not succeed_sink then get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Put_Debug ("Tag6"); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); end if; else -- connex : adding edge only if (succeed_source or succeed_sink) then Add (res, graph_union (temp_connex_graph, current_graph)); Delete (res, temp_connex_graph); Put_Debug ("Tag7"); Delete (res, current_graph); end if; end if; Next_Element (res, G_Iterator); Current_Element (res, current_graph, G_Iterator); Put_Debug ("Tag8"); end loop; Put_Debug ("Tag8bis"); --detecting connexity for last element get_task_node_by_task_name (current_graph, current_edge.all.Node_1, succeed_source, current_node_source); Put_Debug ("Tag8ter"); get_task_node_by_task_name (current_graph, current_edge.all.Node_2, succeed_sink, current_node_sink); Put_Debug ("Tag9"); if (succeed_source or succeed_sink) and not connex then -- -- not connex : adding edge Add_Generic_Edge (current_graph, current_edge, succeed_add); connex := True; temp_connex_graph := current_graph; Put_Debug ("Tag10"); -- connex : adding node1 if necessary if not succeed_source then get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); Put_Debug ("Tag11"); end if; -- connex : adding node2 if necessary if not succeed_sink then get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Put_Debug ("Tag12"); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); end if; else Put_Debug ("Tag13"); -- connex : adding edge only if (succeed_source or succeed_sink) then Add (res, graph_union (temp_connex_graph, current_graph)); Put_Debug ("Tag14"); Delete (res, temp_connex_graph); Delete (res, current_graph); end if; end if; end if; -- creating a connex graph instance from dependency put_debug("creating a connex graph instance from dependency"); if not connex then Initialize (current_graph); Add_Generic_Edge (current_graph, current_edge, succeed_add); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); Add (res, current_graph); end if; Next_Element (obj.Edges, E_Iterator); Current_Element (obj.Edges, current_edge, E_Iterator); put_debug("next dependency"); -- CHANGE False -> True connex := False; --Put_Debug ("connex := true"); end loop; Reset_Head_Iterator (res, G_Iterator); -- Dealing with last dependency put_debug("Dealing with last dependency"); put_debug("G_list size :" & To_Unbounded_String (Get_Number_Of_Elements (res)'IMG)); put(current_edge); if not Is_Empty (res) then Current_Element (res, current_graph, G_Iterator); while (not Is_Tail_Element (res, G_Iterator)) loop -- Browsing connex graph instances put_debug("Browsing connex graph instances"); get_task_node_by_task_name (current_graph, current_edge.all.Node_1, succeed_source, current_node_source); get_task_node_by_task_name (current_graph, current_edge.all.Node_2, succeed_sink, current_node_sink); if (succeed_source or succeed_sink) and not connex then Add_Generic_Edge (current_graph, current_edge, succeed_add); connex := True; temp_connex_graph := current_graph; if not succeed_source then get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); end if; if not succeed_sink then get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); end if; else if (succeed_source or succeed_sink) then Add (res, graph_union (temp_connex_graph, current_graph)); Delete (res, temp_connex_graph); Delete (res, current_graph); end if; end if; Next_Element (res, G_Iterator); Current_Element (res, current_graph, G_Iterator); end loop; -- Dealing with last graph instance and last dependency put_debug("Dealing with last graph instance and last dependency"); put_debug("Dependency"); put(current_edge); put_debug("Graph"); put(current_graph); get_task_node_by_task_name (current_graph, current_edge.all.Node_1, succeed_source, current_node_source); get_task_node_by_task_name (current_graph, current_edge.all.Node_2, succeed_sink, current_node_sink); put_debug("succeed_source :" & To_Unbounded_String (succeed_source'IMG)); put_debug("succeed_sink :" & To_Unbounded_String (succeed_sink'IMG)); if (succeed_source or succeed_sink) and not connex then Add_Generic_Edge (current_graph, current_edge, succeed_add); connex := True; temp_connex_graph := current_graph; if not succeed_source then get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); end if; if not succeed_sink then get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); end if; else if (succeed_source or succeed_sink) then Add (res, graph_union (temp_connex_graph, current_graph)); Delete (res, temp_connex_graph); Delete (res, current_graph); end if; end if; end if; if not connex then -- creating a new graph for last dependency put_debug("creating a new graph for last dependency"); Initialize (current_graph); Add_Generic_Edge (current_graph, current_edge, succeed_add); get_task_node_by_task_name (obj, current_edge.all.Node_1, succeed_source, current_node_source); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_source)), succeed_add); get_task_node_by_task_name (obj, current_edge.all.Node_2, succeed_sink, current_node_sink); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node_sink)), succeed_add); Add (res, current_graph); end if; end if; -- adding unplugged nodes Reset_Head_Iterator (obj.Nodes, N_Iterator); if not Is_Empty (obj.Nodes) then Current_Element (obj.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (obj.Nodes, N_Iterator)) loop put_debug("adding unplugged node"); connex := False; Reset_Head_Iterator (res, G_Iterator); if not Is_Empty (res) then Current_Element (res, current_graph, G_Iterator); connex := False; while (not Is_Tail_Element (res, G_Iterator)) loop get_task_node_by_task_name (current_graph, current_node.cheddar_private_id , succeed_add, current_node_source); connex := succeed_add or connex; Next_Element (res, G_Iterator); Current_Element (res, current_graph, G_Iterator); end loop; get_task_node_by_task_name (current_graph, current_node.cheddar_private_id , succeed_add, current_node_source); connex := succeed_add or connex; end if; if not connex then put_debug("Failed to recognize node"); Initialize (current_graph); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node)), succeed_add); Add (res, current_graph); end if; Next_Element (obj.Nodes, N_Iterator); Current_Element (obj.Nodes, current_node, N_Iterator); end loop; connex := False; Reset_Head_Iterator (res, G_Iterator); if not Is_Empty (res) then Current_Element (res, current_graph, G_Iterator); connex := False; while (not Is_Tail_Element (res, G_Iterator)) loop get_task_node_by_task_name (current_graph, current_node.cheddar_private_id , succeed_add, current_node_source); connex := succeed_add or connex; Next_Element (res, G_Iterator); Current_Element (res, current_graph, G_Iterator); end loop; get_task_node_by_task_name (current_graph, current_node.cheddar_private_id , succeed_add, current_node_source); connex := succeed_add or connex; end if; if not connex then put_debug("adding unplugged node"); Initialize (current_graph); Add_Generic_Node (current_graph, Generic_Node_Ptr (Copy (current_node)), succeed_add); Add (res, current_graph); end if; end if; return res; end Connexity_View; --View based on processors's names -- function Processor_View (obj : in Graph) return Graph_List is res : Graph_List; begin Initialize (res); return res; end Processor_View; function Processor_View (obj : in Graph; processor_name : in Unbounded_String) return Graph is begin return obj; end Processor_View; --Sub-System from Original system and a view -- function Get_Subsystem_From_Graph (obj : in Graph; original : in System) return System is begin return original; end Get_Subsystem_From_Graph; --Annex functionnalities -- procedure get_task_node_by_task_name (obj : in Graph_Ptr; task_name : in Unbounded_String; succeed : out Boolean; res : out Task_Node_Ptr) is N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; begin Initialize (res); if not Is_Empty (obj.all.Nodes) then Reset_Head_Iterator (obj.all.Nodes, N_Iterator); Current_Element (obj.all.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (obj.all.Nodes, N_Iterator)) and not (current_node.cheddar_private_id = task_name) loop Next_Element (obj.all.Nodes, N_Iterator); Current_Element (obj.all.Nodes, current_node, N_Iterator); end loop; else succeed := False; end if; if (current_node.cheddar_private_id = task_name) then succeed := True; res := Copy (Task_Node_Ptr (current_node)); else succeed := False; end if; end get_task_node_by_task_name; procedure get_task_node_by_task_name (obj : in Graph; task_name : in Unbounded_String; succeed : out Boolean; res : out Task_Node_Ptr) is N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; begin Initialize (res); Reset_Head_Iterator (obj.Nodes, N_Iterator); if not Is_Empty (obj.Nodes) then Current_Element (obj.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (obj.Nodes, N_Iterator)) and not (current_node.cheddar_private_id = task_name) loop Next_Element (obj.Nodes, N_Iterator); Current_Element (obj.Nodes, current_node, N_Iterator); end loop; else succeed := False; end if; if (current_node.cheddar_private_id = task_name) then succeed := True; res := Copy (Task_Node_Ptr (current_node)); else succeed := False; end if; end get_task_node_by_task_name; function task_node_in_graph (obj : in Graph; task_name : in Unbounded_String) return Boolean is N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; res : Boolean; begin put_debug(To_Unbounded_String ("Nodes: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.nodes)'IMG)); put_debug(To_Unbounded_String ("Edges: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.edges)'IMG)); res := False; Reset_Head_Iterator (obj.Nodes, N_Iterator); if not Is_Empty (obj.Nodes) then Current_Element (obj.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (obj.Nodes, N_Iterator)) and not (current_node.cheddar_private_id = task_name) loop Next_Element (obj.Nodes, N_Iterator); Current_Element (obj.Nodes, current_node, N_Iterator); end loop; else return res; end if; if (current_node.cheddar_private_id = task_name) then res := True; else res := False; end if; return res; end task_node_in_graph; function dependency_edge_in_graph (obj : in Graph; edge_name : in Unbounded_String) return Boolean is E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; res : Boolean; begin put_debug(To_Unbounded_String ("Nodes: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.nodes)'IMG)); put_debug(To_Unbounded_String ("Edges: ") & To_Unbounded_String (Get_Number_Of_Elements (obj.edges)'IMG)); res := False; Reset_Head_Iterator (obj.Edges, E_Iterator); if not Is_Empty (obj.Edges) then Current_Element (obj.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (obj.Edges, E_Iterator)) and not (current_edge.cheddar_private_id = edge_name) loop Next_Element (obj.Edges, E_Iterator); Current_Element (obj.Edges, current_edge, E_Iterator); end loop; else put_line(" ");put_line(" "); Put_line("dependency edge in graph: FALSE1");put_line(" ");put_line(" "); return res; end if; if (current_edge.cheddar_private_id = edge_name) then res := True; put_line(" ");put_line(" "); Put_line("dependency edge in graph: TRUE");put_line(" ");put_line(" "); else res := False; Put_line("dependency edge in graph: FALSE2"); end if; return res; end dependency_edge_in_graph; --Binary Operators -- function graph_minus (graph_a : in Graph; graph_b : in Graph) return Graph is res : Graph; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; succeed : Boolean; begin Initialize (res); Reset_Head_Iterator (graph_a.Edges, E_Iterator); if not Is_Empty (graph_a.Edges) then Current_Element (graph_a.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (graph_a.Edges, E_Iterator)) loop succeed := dependency_edge_in_graph (graph_b, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; Next_Element (graph_a.Edges, E_Iterator); Current_Element (graph_a.Edges, current_edge, E_Iterator); end loop; succeed := dependency_edge_in_graph (graph_b, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; end if; Reset_Head_Iterator (graph_b.Edges, E_Iterator); if not Is_Empty (graph_b.Edges) then Current_Element (graph_b.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (graph_b.Edges, E_Iterator)) loop succeed := dependency_edge_in_graph (graph_a, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; Next_Element (graph_b.Edges, E_Iterator); Current_Element (graph_b.Edges, current_edge, E_Iterator); end loop; succeed := dependency_edge_in_graph (graph_a, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; end if; Reset_Head_Iterator (graph_a.Nodes, N_Iterator); if not Is_Empty (graph_a.Nodes) then Current_Element (graph_a.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (graph_a.Nodes, N_Iterator)) loop succeed := task_node_in_graph (graph_b, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; Next_Element (graph_a.Nodes, N_Iterator); Current_Element (graph_a.Nodes, current_node, N_Iterator); end loop; succeed := task_node_in_graph (graph_b, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; end if; Reset_Head_Iterator (graph_b.Nodes, N_Iterator); if not Is_Empty (graph_b.Nodes) then Current_Element (graph_b.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (graph_b.Nodes, N_Iterator)) loop succeed := task_node_in_graph (graph_a, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; Next_Element (graph_b.Nodes, N_Iterator); Current_Element (graph_b.Nodes, current_node, N_Iterator); end loop; succeed := task_node_in_graph (graph_a, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; end if; return res; end graph_minus; function graph_union (graph_a : in Graph; graph_b : in Graph) return Graph is res : Graph; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; succeed : Boolean; begin Initialize (res); Duplicate (graph_b.Nodes, res.Nodes, false); Duplicate (graph_b.Edges, res.Edges, false); --Edge union Reset_Head_Iterator (graph_a.Edges, E_Iterator); if not Is_Empty (graph_a.Edges) then Current_Element (graph_a.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (graph_a.Edges, E_Iterator)) loop succeed := dependency_edge_in_graph (graph_b, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; Next_Element (graph_a.Edges, E_Iterator); Current_Element (graph_a.Edges, current_edge, E_Iterator); end loop; succeed := dependency_edge_in_graph (graph_b, current_edge.cheddar_private_id ); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; end if; --Node union Reset_Head_Iterator (graph_a.Nodes, N_Iterator); if not Is_Empty (graph_a.Nodes) then Current_Element (graph_a.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (graph_a.Nodes, N_Iterator)) loop succeed := task_node_in_graph (graph_b, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; Next_Element (graph_a.Nodes, N_Iterator); Current_Element (graph_a.Nodes, current_node, N_Iterator); end loop; succeed := task_node_in_graph (graph_b, current_node.cheddar_private_id ); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; end if; return res; end graph_union; function graph_union (graph_a : in Graph_Ptr; graph_b : in Graph_Ptr) return Graph_Ptr is res : Graph_Ptr; E_Iterator : Edge_Lists_Iterator; current_edge : Generic_Edge_Ptr; N_Iterator : Node_Lists_Iterator; current_node : Generic_Node_Ptr; succeed : Boolean; begin Initialize (res); Duplicate (graph_b.all.Nodes, res.Nodes, false); Duplicate (graph_b.all.Edges, res.Edges, false); --Edge union Reset_Head_Iterator (graph_a.all.Edges, E_Iterator); if not Is_Empty (graph_a.all.Edges) then Current_Element (graph_a.all.Edges, current_edge, E_Iterator); while (not Is_Tail_Element (graph_a.all.Edges, E_Iterator)) loop succeed := Edge_In_Graph (current_edge, graph_b); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; Next_Element (graph_a.all.Edges, E_Iterator); Current_Element (graph_a.all.Edges, current_edge, E_Iterator); end loop; succeed := Edge_In_Graph (current_edge, graph_b); if not succeed then Add_Generic_Edge (res, current_edge, succeed); end if; end if; --Node union Reset_Head_Iterator (graph_a.all.Nodes, N_Iterator); if not Is_Empty (graph_a.all.Nodes) then Current_Element (graph_a.all.Nodes, current_node, N_Iterator); while (not Is_Tail_Element (graph_a.all.Nodes, N_Iterator)) loop succeed := Node_In_Graph (current_node, graph_b); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; Next_Element (graph_a.all.Nodes, N_Iterator); Current_Element (graph_a.all.Nodes, current_node, N_Iterator); end loop; succeed := Node_In_Graph (current_node, graph_b); if not succeed then Add_Generic_Node (res, current_node, succeed); end if; end if; return res; end graph_union; --Composition Analysis -- function potential_design_pattern (g : in Graph) return design_pattern is G2 : Graph; G3 : Graph; begin Put_debug("compo analysis begin"); if (Get_Number_Of_Elements (g.Edges) = 0) then Put_debug("compo analysis Unplugged"); return unplugged; end if; G2 := Time_Triggered_Communication_View (g); -- if ((Get_Number_Of_Elements (graph_minus (g, G2).Nodes) = 0) and -- (Get_Number_Of_Elements (graph_minus (g, G2).Edges) = 0)) if ((Get_Number_Of_Elements (graph_minus (g, g).Nodes) = 0) and (Get_Number_Of_Elements (graph_minus (g, g).Edges) = 0)) then Put_debug("compo analysis Time Triggered"); return Time_Triggered_Communication; end if; G3 := Resource_View (g); if ((Get_Number_Of_Elements (graph_minus (g, G3).Nodes) = 0) and (Get_Number_Of_Elements (graph_minus (g, G3).Edges) = 0)) then Put_debug("compo analysis ravenscar"); return ravenscar; end if; Put_debug("compo analysis end"); raise Unrecognized_design_pattern; end potential_design_pattern; function compose (g_list : in Graph_List) return design_pattern is G_Iterator : Graph_List_Iterator; current_graph : Graph_Ptr; global_design_pattern : design_pattern; begin global_design_pattern := unplugged; Reset_Head_Iterator (g_list, G_Iterator); if not Is_Empty (g_list) then loop Current_Element (g_list, current_graph, G_Iterator); global_design_pattern := compose_aux (global_design_pattern, current_graph); exit when Is_Tail_Element (g_list, G_Iterator); Next_Element (g_list, G_Iterator); end loop; global_design_pattern := compose_aux (global_design_pattern, current_graph); end if; return global_design_pattern; end compose; function compose_aux (dp : in design_pattern; g : in Graph_Ptr) return design_pattern is dp2 : design_pattern; begin dp2 := potential_design_pattern (get_value (g)); case dp is when unplugged => case dp2 is when unplugged => return unplugged; when Time_Triggered_Communication => return Time_Triggered_Communication; when ravenscar => return ravenscar; when others => raise Unrecognized_design_pattern; end case; when Time_Triggered_Communication => case dp2 is when unplugged => return Time_Triggered_Communication; when Time_Triggered_Communication => return Time_Triggered_Communication; when ravenscar => return ravenscar; when others => raise Unrecognized_design_pattern; end case; when ravenscar => case dp2 is when unplugged => return ravenscar; when Time_Triggered_Communication => return ravenscar; when ravenscar => return ravenscar; when others => raise Unrecognized_design_pattern; end case; when others => raise Unrecognized_design_pattern; end case; end compose_aux; end DP_Graph_view;