------------------------------------------------------------------------------ -- 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 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 Initialize (res); Reset_Head_Iterator (obj.Edges, E_Iterator); if not Is_Empty (obj.Edges) then Current_Element (obj.Edges, current_edge, E_Iterator); connex := False; while (not Is_Tail_Element (obj.Edges, E_Iterator)) loop -- 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_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; 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; end if; 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); connex := False; end loop; Reset_Head_Iterator (res, G_Iterator); if not Is_Empty (res) then Current_Element (res, current_graph, G_Iterator); 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); 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; 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; end if; 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; 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 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.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.Id, succeed_add, current_node_source); connex := succeed_add or connex; end if; if not connex then 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.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.Id, succeed_add, current_node_source); connex := succeed_add or connex; end if; if not connex then 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.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.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.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.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 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.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.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 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.Id = edge_name) loop Next_Element (obj.Edges, E_Iterator); Current_Element (obj.Edges, current_edge, E_Iterator); end loop; else return res; end if; if (current_edge.Id = edge_name) then res := True; else res := False; 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.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.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.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.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.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.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.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.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.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.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.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.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 if (Get_Number_Of_Elements (g.Edges) = 0) then 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)) then 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 return ravenscar; end if; 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;