1. -- 
  2. --  Uwe R. Zimmer, Australia, September 2011 
  3. -- 
  4.  
  5. package body Topologies is 
  6.  
  7.    --  Basic topology parameters 
  8.  
  9.    type Topology_by_Size is abstract new Topology_Kind with record 
  10.       Size : Positive; 
  11.    end record; 
  12.  
  13.    type Topology_by_Dimension is abstract new Topology_Kind with record 
  14.       Dimension : Positive; 
  15.    end record; 
  16.  
  17.    type Topology_by_Dimension_and_Size is abstract new Topology_by_Dimension with record 
  18.       Size : Positive; 
  19.    end record; 
  20.  
  21.    type Topology_by_Degree is abstract new Topology_Kind with record 
  22.       Degree : Positive; 
  23.    end record; 
  24.  
  25.    type Topology_by_Degree_and_Depths is abstract new Topology_by_Degree with record 
  26.       Depths : Positive; 
  27.    end record; 
  28.  
  29.    -- 
  30.  
  31.    pragma Warnings (Off); -- all overriding operations cause hiding 
  32.  
  33.    --  Cube_Connected_Cycles 
  34.  
  35.    type Topology_Cube_Connected_Cycles is new Topology_by_Dimension with null record; 
  36.  
  37.    overriding function Nodes_in_Topology (Configuration : Topology_Cube_Connected_Cycles) return Positive; 
  38.  
  39.    overriding function Nodes_Connected (Configuration   : Topology_Cube_Connected_Cycles; 
  40.                                         Node_A, Node_B : Positive) return Boolean; 
  41.  
  42.    --  Trees 
  43.  
  44.    type Topology_Trees is new Topology_by_Degree_and_Depths with null record; 
  45.  
  46.    overriding function Nodes_in_Topology (Configuration : Topology_Trees) return Positive; 
  47.  
  48.    overriding function Nodes_Connected (Configuration   : Topology_Trees; 
  49.                                         Node_A, Node_B : Positive) return Boolean; 
  50.  
  51.    --  Mesh 
  52.  
  53.    type Topology_Mesh is new Topology_by_Dimension_and_Size with null record; 
  54.  
  55.    overriding function Nodes_in_Topology (Configuration : Topology_Mesh) return Positive; 
  56.  
  57.    overriding function Nodes_Connected (Configuration   : Topology_Mesh; 
  58.                                         Node_A, Node_B : Positive) return Boolean; 
  59.  
  60.    --  Torus 
  61.  
  62.    type Topology_Torus is new Topology_by_Dimension_and_Size with null record; 
  63.  
  64.    overriding function Nodes_in_Topology (Configuration : Topology_Torus) return Positive; 
  65.  
  66.    overriding function Nodes_Connected (Configuration   : Topology_Torus; 
  67.                                         Node_A, Node_B : Positive) return Boolean; 
  68.  
  69.    --  Butterfly 
  70.  
  71.    type Topology_Butterfly is new Topology_by_Dimension with null record; 
  72.  
  73.    overriding function Nodes_in_Topology (Configuration : Topology_Butterfly) return Positive; 
  74.  
  75.    overriding function Nodes_Connected (Configuration   : Topology_Butterfly; 
  76.                                         Node_A, Node_B : Positive) return Boolean; 
  77.  
  78.    --  Wrap_Around_Butterfly 
  79.  
  80.    type Topology_Wrap_Around_Butterfly is new Topology_by_Dimension with null record; 
  81.  
  82.    overriding function Nodes_in_Topology (Configuration : Topology_Wrap_Around_Butterfly) return Positive; 
  83.  
  84.    overriding function Nodes_Connected (Configuration   : Topology_Wrap_Around_Butterfly; 
  85.                                         Node_A, Node_B : Positive) return Boolean; 
  86.  
  87.    --  Star 
  88.  
  89.    type Topology_Star is new Topology_by_Size with null record; 
  90.  
  91.    overriding function Nodes_in_Topology (Configuration : Topology_Star) return Positive; 
  92.  
  93.    overriding function Nodes_Connected (Configuration   : Topology_Star; 
  94.                                         Node_A, Node_B : Positive) return Boolean; 
  95.  
  96.    --  Fully_Connected 
  97.  
  98.    type Topology_Fully_Connected is new Topology_by_Size with null record; 
  99.  
  100.    overriding function Nodes_in_Topology (Configuration : Topology_Fully_Connected) return Positive; 
  101.  
  102.    overriding function Nodes_Connected (Configuration   : Topology_Fully_Connected; 
  103.                                         Node_A, Node_B : Positive) return Boolean; 
  104.  
  105.    -- 
  106.  
  107.    pragma Warnings (On); 
  108.  
  109.    -- 
  110.  
  111.    --  Cube_Connected_Cycles 
  112.  
  113.    overriding function Nodes_in_Topology (Configuration : Topology_Cube_Connected_Cycles) return Positive is 
  114.  
  115.    begin 
  116.       return Configuration.Dimension * (2 ** (Configuration.Dimension)); 
  117.    end Nodes_in_Topology; 
  118.  
  119.    overriding function Nodes_Connected (Configuration   : Topology_Cube_Connected_Cycles; 
  120.                                         Node_A, Node_B : Positive) return Boolean is 
  121.  
  122.       subtype Corners is Natural range 0 .. (2 ** (Configuration.Dimension)) - 1; 
  123.       subtype Cycles  is Natural range 0 .. Configuration.Dimension - 1; 
  124.  
  125.       type CCC_Coordinates is record 
  126.          Corner_Nr   : Corners; 
  127.          Cycle_Nr    : Cycles; 
  128.       end record; 
  129.  
  130.       function To_CCC_Coordinates (Node : Positive) return CCC_Coordinates is 
  131.  
  132.          Coordinate : constant CCC_Coordinates := (Corner_Nr => (Node - 1) /   Configuration.Dimension, 
  133.                                                    Cycle_Nr  => (Node - 1) mod Configuration.Dimension); 
  134.  
  135.       begin 
  136.          return Coordinate; 
  137.       end To_CCC_Coordinates; 
  138.  
  139.       CCC_Node_A : constant CCC_Coordinates := To_CCC_Coordinates (Node_A); 
  140.       CCC_Node_B : constant CCC_Coordinates := To_CCC_Coordinates (Node_B); 
  141.  
  142.       type Bit_Arrays is array (Cycles) of Boolean; 
  143.  
  144.       function Bit_Array (Corner_Nr : Corners) return Bit_Arrays is 
  145.  
  146.          Bits : Bit_Arrays; 
  147.  
  148.       begin 
  149.          for Bit in Bits'Range loop 
  150.             Bits (Bit) := (Corner_Nr / (2 ** Bit)) mod 2 > 0; 
  151.          end loop; 
  152.          return Bits; 
  153.       end Bit_Array; 
  154.  
  155.       function Invert_Bit (Bit_Nr : Cycles; Bits : Bit_Arrays) return Bit_Arrays is 
  156.  
  157.          Return_Bits : Bit_Arrays := Bits; 
  158.  
  159.       begin 
  160.          Return_Bits (Bit_Nr) := not Return_Bits (Bit_Nr); 
  161.          return Return_Bits; 
  162.       end Invert_Bit; 
  163.  
  164.    begin 
  165.       return (CCC_Node_A.Corner_Nr = CCC_Node_B.Corner_Nr 
  166.         and then (CCC_Node_A.Cycle_Nr = (CCC_Node_B.Cycle_Nr + 1) mod Configuration.Dimension 
  167.           or else CCC_Node_A.Cycle_Nr = (CCC_Node_B.Cycle_Nr - 1) mod Configuration.Dimension)) 
  168.         or else (CCC_Node_A.Cycle_Nr = CCC_Node_B.Cycle_Nr 
  169.                  and then Bit_Array (CCC_Node_A.Corner_Nr) = Invert_Bit (CCC_Node_A.Cycle_Nr, Bit_Array (CCC_Node_B.Corner_Nr))); 
  170.    end Nodes_Connected; 
  171.  
  172.    --  Trees 
  173.  
  174.    overriding function Nodes_in_Topology (Configuration : Topology_Trees) return Positive is 
  175.  
  176.       Nodes : Positive := 1; 
  177.  
  178.    begin 
  179.       for Level in 1 .. Configuration.Depths - 1 loop 
  180.          Nodes := Nodes + (Configuration.Degree ** Level); 
  181.       end loop; 
  182.       return Nodes; 
  183.    end Nodes_in_Topology; 
  184.  
  185.    overriding function Nodes_Connected (Configuration   : Topology_Trees; 
  186.                                         Node_A, Node_B : Positive) return Boolean is 
  187.  
  188.       Node_Nr : Positive := 1; 
  189.  
  190.       function Construct_Tree (Parent_Nr, Depth : Positive) return Boolean is 
  191.  
  192.       begin 
  193.          if Depth <= Configuration.Depths then 
  194.             for i in 1 .. Configuration.Degree loop 
  195.                Node_Nr := Node_Nr + 1; 
  196.                if (Parent_Nr = Node_A and then Node_Nr = Node_B) 
  197.                  or else (Parent_Nr = Node_B and then Node_Nr = Node_A) then 
  198.                   return True; 
  199.                else 
  200.                   if Construct_Tree (Node_Nr, Depth + 1) then 
  201.                      return True; 
  202.                   end if; 
  203.                end if; 
  204.             end loop; 
  205.             return False; 
  206.          else 
  207.             return False; 
  208.          end if; 
  209.       end Construct_Tree; 
  210.  
  211.    begin 
  212.       return Construct_Tree (Node_Nr, 2); 
  213.    end Nodes_Connected; 
  214.  
  215.    --  Mesh 
  216.  
  217.    overriding function Nodes_in_Topology (Configuration : Topology_Mesh) return Positive is 
  218.  
  219.    begin 
  220.       return Configuration.Size ** Configuration.Dimension; 
  221.    end Nodes_in_Topology; 
  222.  
  223.    overriding function Nodes_Connected (Configuration   : Topology_Mesh; 
  224.                                         Node_A, Node_B : Positive) return Boolean is 
  225.  
  226.       subtype Nodes_in_Line is Natural range 0 .. Configuration.Size - 1; 
  227.       type Coordinates is array (0 .. Configuration.Dimension - 1) of Nodes_in_Line; 
  228.  
  229.       function To_Coordinates (Node_Nr : Positive) return Coordinates is 
  230.  
  231.          Coordinate : Coordinates; 
  232.  
  233.       begin 
  234.          for Dim in 0 .. Coordinate'Last loop 
  235.             Coordinate (Dim) := (Node_Nr - 1) / Configuration.Size ** Dim mod Configuration.Size; 
  236.          end loop; 
  237.          return Coordinate; 
  238.       end To_Coordinates; 
  239.  
  240.       Coordinate_A : constant Coordinates := To_Coordinates (Node_A); 
  241.       Coordinate_B : constant Coordinates := To_Coordinates (Node_B); 
  242.  
  243.       Matching_Coordinates : Natural := 0; 
  244.  
  245.    begin 
  246.       for Dim in Coordinates'Range loop 
  247.          if Coordinate_A (Dim) = Coordinate_B (Dim) then 
  248.             Matching_Coordinates := Matching_Coordinates + 1; 
  249.          end if; 
  250.       end loop; 
  251.       if Matching_Coordinates = Configuration.Dimension - 1 then 
  252.          for Dim in Coordinates'Range loop 
  253.             if      (Coordinate_A (Dim) < Nodes_in_Line'Last and then Coordinate_A (Dim) + 1 = Coordinate_B (Dim)) 
  254.               or else (Coordinate_B (Dim) < Nodes_in_Line'Last and then Coordinate_B (Dim) + 1 = Coordinate_A (Dim)) then 
  255.                return True; 
  256.             end if; 
  257.          end loop; 
  258.          return False; 
  259.       else 
  260.          return False; 
  261.       end if; 
  262.    end Nodes_Connected; 
  263.  
  264.    --  Torus 
  265.  
  266.    overriding function Nodes_in_Topology (Configuration : Topology_Torus) return Positive is 
  267.  
  268.    begin 
  269.       return Configuration.Size ** Configuration.Dimension; 
  270.    end Nodes_in_Topology; 
  271.  
  272.    overriding function Nodes_Connected (Configuration   : Topology_Torus; 
  273.                                         Node_A, Node_B : Positive) return Boolean is 
  274.  
  275.       subtype Nodes_in_Line is Natural range 0 .. Configuration.Size - 1; 
  276.       type Coordinates is array (0 .. Configuration.Dimension - 1) of Nodes_in_Line; 
  277.  
  278.       function To_Coordinates (Node_Nr : Positive) return Coordinates is 
  279.  
  280.          Coordinate : Coordinates; 
  281.  
  282.       begin 
  283.          for Dim in 0 .. Coordinate'Last loop 
  284.             Coordinate (Dim) := (Node_Nr - 1) / Configuration.Size ** Dim mod Configuration.Size; 
  285.          end loop; 
  286.          return Coordinate; 
  287.       end To_Coordinates; 
  288.  
  289.       Coordinate_A : constant Coordinates := To_Coordinates (Node_A); 
  290.       Coordinate_B : constant Coordinates := To_Coordinates (Node_B); 
  291.  
  292.       Matching_Coordinates : Natural := 0; 
  293.  
  294.    begin 
  295.       for Dim in Coordinates'Range loop 
  296.          if Coordinate_A (Dim) = Coordinate_B (Dim) then 
  297.             Matching_Coordinates := Matching_Coordinates + 1; 
  298.          end if; 
  299.       end loop; 
  300.       if Matching_Coordinates = Configuration.Dimension - 1 then 
  301.          for Dim in Coordinates'Range loop 
  302.             if      (Coordinate_A (Dim) + 1) mod Configuration.Size = Coordinate_B (Dim) 
  303.               or else (Coordinate_B (Dim) + 1) mod Configuration.Size = Coordinate_A (Dim) then 
  304.                return True; 
  305.             end if; 
  306.          end loop; 
  307.          return False; 
  308.       else 
  309.          return False; 
  310.       end if; 
  311.    end Nodes_Connected; 
  312.  
  313.    --  Butterfly 
  314.  
  315.    overriding function Nodes_in_Topology (Configuration : Topology_Butterfly) return Positive is 
  316.  
  317.    begin 
  318.       return (Configuration.Dimension + 1) * (2 ** Configuration.Dimension); 
  319.    end Nodes_in_Topology; 
  320.  
  321.    overriding function Nodes_Connected (Configuration   : Topology_Butterfly; 
  322.                                         Node_A, Node_B : Positive) return Boolean is 
  323.  
  324.       subtype Lines  is Natural range 0 .. (2 ** (Configuration.Dimension)) - 1; 
  325.       subtype Layers is Natural range 0 .. Configuration.Dimension; 
  326.       subtype Bits   is Natural range 0 .. Configuration.Dimension - 1; 
  327.  
  328.       type Butterfly_Coordinates is record 
  329.          Line  : Lines; 
  330.          Layer : Layers; 
  331.       end record; 
  332.  
  333.       function To_Butterfly_Coordinates (Node : Positive) return Butterfly_Coordinates is 
  334.  
  335.          Coordinate : constant Butterfly_Coordinates := (Line  => (Node - 1) /   (Configuration.Dimension + 1), 
  336.                                                          Layer => (Node - 1) mod (Configuration.Dimension + 1)); 
  337.  
  338.       begin 
  339.          return Coordinate; 
  340.       end To_Butterfly_Coordinates; 
  341.  
  342.       Butterfly_A : constant Butterfly_Coordinates := To_Butterfly_Coordinates (Node_A); 
  343.       Butterfly_B : constant Butterfly_Coordinates := To_Butterfly_Coordinates (Node_B); 
  344.  
  345.       type Bit_Arrays is array (Bits) of Boolean; 
  346.  
  347.       function To_Bit_Arrays (Line_Nr : Lines) return Bit_Arrays is 
  348.  
  349.          Bit_Array : Bit_Arrays; 
  350.  
  351.       begin 
  352.          for Bit in Bits'Range loop 
  353.             Bit_Array (Bit) := (Line_Nr / (2 ** Bit)) mod 2 > 0; 
  354.          end loop; 
  355.          return Bit_Array; 
  356.       end To_Bit_Arrays; 
  357.  
  358.       function Invert_Bit (Bit_Nr : Bits; Bit_Array : Bit_Arrays) return Bit_Arrays is 
  359.  
  360.          Return_Bits : Bit_Arrays := Bit_Array; 
  361.  
  362.       begin 
  363.          Return_Bits (Bit_Nr) := not Return_Bits (Bit_Nr); 
  364.          return Return_Bits; 
  365.       end Invert_Bit; 
  366.  
  367.    begin 
  368.       return         ((Butterfly_A.Layer < Layers'Last and then Butterfly_A.Layer + 1 = Butterfly_B.Layer) 
  369.                       or else (Butterfly_B.Layer < Layers'Last and then Butterfly_B.Layer + 1 = Butterfly_A.Layer)) 
  370.         and then           (Butterfly_A.Line = Butterfly_B.Line 
  371.                             or else ((Butterfly_A.Layer < Butterfly_B.Layer) 
  372.                                      and then To_Bit_Arrays (Butterfly_A.Line) = Invert_Bit (Butterfly_A.Layer, To_Bit_Arrays (Butterfly_B.Line))) 
  373.                             or else ((Butterfly_B.Layer < Butterfly_A.Layer) 
  374.                                      and then To_Bit_Arrays (Butterfly_B.Line) = Invert_Bit (Butterfly_B.Layer, To_Bit_Arrays (Butterfly_A.Line)))); 
  375.    end Nodes_Connected; 
  376.  
  377.    --  Wrap_Around_Butterfly 
  378.  
  379.    overriding function Nodes_in_Topology (Configuration : Topology_Wrap_Around_Butterfly) return Positive is 
  380.  
  381.    begin 
  382.       return Configuration.Dimension * (2 ** Configuration.Dimension); 
  383.    end Nodes_in_Topology; 
  384.  
  385.    overriding function Nodes_Connected (Configuration   : Topology_Wrap_Around_Butterfly; 
  386.                                         Node_A, Node_B : Positive) return Boolean is 
  387.  
  388.       subtype Lines  is Natural range 0 .. (2 ** (Configuration.Dimension)) - 1; 
  389.       subtype Layers is Natural range 0 .. Configuration.Dimension - 1; 
  390.       subtype Bits   is Natural range 0 .. Configuration.Dimension - 1; 
  391.  
  392.       type Butterfly_Coordinates is record 
  393.          Line  : Lines; 
  394.          Layer : Layers; 
  395.       end record; 
  396.  
  397.       function To_Butterfly_Coordinates (Node : Positive) return Butterfly_Coordinates is 
  398.  
  399.          Coordinate : constant Butterfly_Coordinates := (Line  => (Node - 1) /   Configuration.Dimension, 
  400.                                                          Layer => (Node - 1) mod Configuration.Dimension); 
  401.  
  402.       begin 
  403.          return Coordinate; 
  404.       end To_Butterfly_Coordinates; 
  405.  
  406.       Butterfly_A : constant Butterfly_Coordinates := To_Butterfly_Coordinates (Node_A); 
  407.       Butterfly_B : constant Butterfly_Coordinates := To_Butterfly_Coordinates (Node_B); 
  408.  
  409.       type Bit_Arrays is array (Bits) of Boolean; 
  410.  
  411.       function To_Bit_Arrays (Line_Nr : Lines) return Bit_Arrays is 
  412.  
  413.          Bit_Array : Bit_Arrays; 
  414.  
  415.       begin 
  416.          for Bit in Bits'Range loop 
  417.             Bit_Array (Bit) := (Line_Nr / (2 ** Bit)) mod 2 > 0; 
  418.          end loop; 
  419.          return Bit_Array; 
  420.       end To_Bit_Arrays; 
  421.  
  422.       function Invert_Bit (Bit_Nr : Bits; Bit_Array : Bit_Arrays) return Bit_Arrays is 
  423.  
  424.          Return_Bits : Bit_Arrays := Bit_Array; 
  425.  
  426.       begin 
  427.          Return_Bits (Bit_Nr) := not Return_Bits (Bit_Nr); 
  428.          return Return_Bits; 
  429.       end Invert_Bit; 
  430.  
  431.    begin 
  432.       return         ((Butterfly_A.Layer + 1) mod Configuration.Dimension = Butterfly_B.Layer 
  433.                       or else (Butterfly_B.Layer + 1) mod Configuration.Dimension = Butterfly_A.Layer) 
  434.         and then           (Butterfly_A.Line = Butterfly_B.Line 
  435.                             or else ((Butterfly_A.Layer + 1) mod Configuration.Dimension = Butterfly_B.Layer 
  436.                                      and then To_Bit_Arrays (Butterfly_A.Line) = Invert_Bit (Butterfly_A.Layer, To_Bit_Arrays (Butterfly_B.Line))) 
  437.                             or else ((Butterfly_B.Layer + 1) mod Configuration.Dimension = Butterfly_A.Layer 
  438.                                      and then To_Bit_Arrays (Butterfly_B.Line) = Invert_Bit (Butterfly_B.Layer, To_Bit_Arrays (Butterfly_A.Line)))); 
  439.    end Nodes_Connected; 
  440.  
  441.    --  Star 
  442.  
  443.    overriding function Nodes_in_Topology (Configuration : Topology_Star) return Positive is 
  444.  
  445.    begin 
  446.       return Configuration.Size; 
  447.    end Nodes_in_Topology; 
  448.  
  449.    pragma Warnings (Off); --  Configuration not referenced 
  450.  
  451.    overriding function Nodes_Connected (Configuration   : Topology_Star; 
  452.                                         Node_A, Node_B : Positive) return Boolean is 
  453.  
  454.       pragma Warnings (On); 
  455.  
  456.    begin 
  457.       return Node_A = 1 or else Node_B = 1; 
  458.    end Nodes_Connected; 
  459.  
  460.    --  Fully connected 
  461.  
  462.    overriding function Nodes_in_Topology (Configuration : Topology_Fully_Connected) return Positive is 
  463.  
  464.    begin 
  465.       return Configuration.Size; 
  466.    end Nodes_in_Topology; 
  467.  
  468.    pragma Warnings (Off); --  Parameters not referenced 
  469.  
  470.    overriding function Nodes_Connected (Configuration   : Topology_Fully_Connected; 
  471.                                         Node_A, Node_B : Positive) return Boolean is 
  472.  
  473.       pragma Warnings (On); 
  474.  
  475.    begin 
  476.       return True; 
  477.    end Nodes_Connected; 
  478.  
  479.    -- 
  480.    --  Degrees 
  481.    -- 
  482.  
  483.    function Min_Degree (Configuration : Topology_Kind'Class) return Natural is 
  484.  
  485.       subtype Nodes_Range is Positive range 1 .. Nodes_in_Topology (Configuration); 
  486.  
  487.       Min : Natural := Nodes_Range'Last; 
  488.  
  489.    begin 
  490.       for i in Nodes_Range loop 
  491.          declare 
  492.             Degree : Natural := 0; 
  493.          begin 
  494.             for j in Nodes_Range loop 
  495.                if Nodes_Connected (Configuration, i, j) then 
  496.                   Degree := Degree + 1; 
  497.                end if; 
  498.             end loop; 
  499.             Min := Natural'Min (Min, Degree); 
  500.          end; 
  501.       end loop; 
  502.       return Min; 
  503.    end Min_Degree; 
  504.  
  505.    -- 
  506.  
  507.    function Max_Degree (Configuration   : Topology_Kind'Class) return Natural is 
  508.  
  509.       subtype Nodes_Range is Positive range 1 .. Nodes_in_Topology (Configuration); 
  510.  
  511.       Max : Natural := 0; 
  512.  
  513.    begin 
  514.       for i in Nodes_Range loop 
  515.          declare 
  516.             Degree : Natural := 0; 
  517.          begin 
  518.             for j in Nodes_Range loop 
  519.                if Nodes_Connected (Configuration, i, j) then 
  520.                   Degree := Degree + 1; 
  521.                end if; 
  522.             end loop; 
  523.             Max := Natural'Max (Max, Degree); 
  524.          end; 
  525.       end loop; 
  526.       return Max; 
  527.    end Max_Degree; 
  528.  
  529.    -- 
  530.    --  Constructors 
  531.    -- 
  532.  
  533.    function Line (Size : Positive) return Topology_Kind'Class is 
  534.  
  535.       Topology_Object : constant Topology_Mesh := (Dimension => 1, Size => Size); 
  536.  
  537.    begin 
  538.       return Topology_Object; 
  539.    end Line; 
  540.  
  541.    -- 
  542.  
  543.    function Ring (Size : Positive) return Topology_Kind'Class is 
  544.  
  545.       Topology_Object : constant Topology_Torus := (Dimension => 1, Size => Size); 
  546.  
  547.    begin 
  548.       return Topology_Object; 
  549.    end Ring; 
  550.  
  551.    -- 
  552.  
  553.    function Star (Size : Positive) return Topology_Kind'Class is 
  554.  
  555.       Topology_Object : constant Topology_Star := (Size => Size); 
  556.  
  557.    begin 
  558.       return Topology_Object; 
  559.    end Star; 
  560.  
  561.    -- 
  562.  
  563.    function Fully_Connected (Size : Positive) return Topology_Kind'Class is 
  564.  
  565.       Topology_Object : constant Topology_Fully_Connected := (Size => Size); 
  566.  
  567.    begin 
  568.       return Topology_Object; 
  569.    end Fully_Connected; 
  570.  
  571.    -- 
  572.  
  573.    function Trees (Degree, Depths : Positive) return Topology_Kind'Class is 
  574.  
  575.       Topology_Object : constant Topology_Trees := (Degree => Degree, Depths => Depths); 
  576.  
  577.    begin 
  578.       return Topology_Object; 
  579.    end Trees; 
  580.  
  581.    -- 
  582.  
  583.    function Mesh (Dimension, Size : Positive) return Topology_Kind'Class is 
  584.  
  585.       Topology_Object : constant Topology_Mesh := (Dimension => Dimension, Size => Size); 
  586.  
  587.    begin 
  588.       return Topology_Object; 
  589.    end Mesh; 
  590.  
  591.    -- 
  592.  
  593.    function Torus (Dimension, Size : Positive) return Topology_Kind'Class is 
  594.  
  595.       Topology_Object : constant Topology_Torus := (Dimension => Dimension, Size => Size); 
  596.  
  597.    begin 
  598.       return Topology_Object; 
  599.    end Torus; 
  600.  
  601.    -- 
  602.  
  603.    function Hypercube (Dimension : Positive) return Topology_Kind'Class is 
  604.  
  605.       Topology_Object : constant Topology_Torus := (Dimension => Dimension, Size => 2); 
  606.  
  607.    begin 
  608.       return Topology_Object; 
  609.    end Hypercube; 
  610.  
  611.    -- 
  612.  
  613.    function Cube_Connected_Cycles (Dimension : Positive) return Topology_Kind'Class is 
  614.  
  615.       Topology_Object : constant Topology_Cube_Connected_Cycles := (Dimension => Dimension); 
  616.  
  617.    begin 
  618.       return Topology_Object; 
  619.    end Cube_Connected_Cycles; 
  620.  
  621.    -- 
  622.  
  623.    function Butterfly (Dimension : Positive) return Topology_Kind'Class is 
  624.  
  625.       Topology_Object : constant Topology_Butterfly := (Dimension => Dimension); 
  626.  
  627.    begin 
  628.       return Topology_Object; 
  629.    end Butterfly; 
  630.  
  631.    -- 
  632.  
  633.    function Wrap_Around_Butterfly (Dimension : Positive) return Topology_Kind'Class is 
  634.  
  635.       Topology_Object : constant Topology_Wrap_Around_Butterfly := (Dimension => Dimension); 
  636.  
  637.    begin 
  638.       return Topology_Object; 
  639.    end Wrap_Around_Butterfly; 
  640.  
  641.    -- 
  642.  
  643. end Topologies;