Advertisement
Guest User

Untitled

a guest
Oct 21st, 2018
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ada 11.11 KB | None | 0 0
  1. -- A skeleton of a program for an assignment in programming languages
  2. -- The students should rename the tasks of producers, consumers, and the buffer
  3. -- Then, they should change them so that they would fit their assignments
  4. -- They should also complete the code with constructions that lack there
  5. with Ada.Text_IO; use Ada.Text_IO;
  6. with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
  7. with Ada.Integer_Text_IO;
  8. with Ada.Numerics.Discrete_Random;
  9.  
  10.  
  11. procedure Simulation is
  12.    Number_Of_Products: constant Integer := 5;
  13.    Number_Of_Assemblies: constant Integer := 3;
  14.    Number_Of_Consumers: constant Integer := 3;
  15.    subtype Production_Time_Range is Integer range 3 .. 7;
  16.    subtype Consumption_Time_Range is Integer range 4 .. 8;
  17.    subtype Product_Type is Integer range 1 .. Number_Of_Products;
  18.    subtype Assembly_Type is Integer range 1 .. Number_Of_Assemblies;
  19.    subtype Consumer_Type is Integer range 1 .. Number_Of_Consumers;
  20.    Product_Name: constant array (Product_Type) of String(1 .. 11)
  21.      := ("Soup       ", "Drink      ", "Starter    ", "Dessert    ", "Main course");
  22.    Assembly_Name: constant array (Assembly_Type) of String(1 .. 9)
  23.      := ("Supper   ", "Lunch    ", "Dinner   ");
  24.    package Random_Consumption is new
  25.      Ada.Numerics.Discrete_Random(Consumption_Time_Range);
  26.    package Random_Assembly is new
  27.      Ada.Numerics.Discrete_Random(Assembly_Type);
  28.    type My_Str is new String(1 ..256);
  29.  
  30.  
  31.    -- Producer produces determined product
  32.    task type Producer is
  33.       -- Give the Producer an identity, i.e. the product type
  34.       entry Start(Product: in Product_Type; Production_Time: in Integer);
  35.    end Producer;
  36.  
  37.    -- Consumer gets an arbitrary assembly of several products from the buffer
  38.    task type Consumer is
  39.       -- Give the Consumer an identity
  40.       entry Start(Consumer_Number: in Consumer_Type;
  41.             Consumption_Time: in Integer);
  42.    end Consumer;
  43.  
  44.    -- In the Buffer, products are assemblied into an assembly
  45.    task type Buffer is
  46.       -- Accept a product to the storage provided there is a room for it
  47.       entry Take(Product: in Product_Type; Number: in Integer; isTaken: out Boolean);
  48.       -- Deliver an assembly provided there are enough products for it
  49.       entry Deliver(Assembly: in Assembly_Type; Number: out Integer);
  50.    end Buffer;
  51.  
  52.    P: array ( 1 .. Number_Of_Products ) of Producer;
  53.    K: array ( 1 .. Number_Of_Consumers ) of Consumer;
  54.    B: Buffer;
  55.  
  56.    task body Producer is
  57.       package Random_Production is new
  58.         Ada.Numerics.Discrete_Random(Production_Time_Range);
  59.       G: Random_Production.Generator;   --  generator liczb losowych
  60.       Product_Type_Number: Integer;
  61.       Product_Number: Integer;
  62.       Production: Integer;
  63.       isTaken: Boolean;
  64.    begin
  65.       accept Start(Product: in Product_Type; Production_Time: in Integer) do
  66.          Random_Production.Reset(G);    --  start random number generator
  67.          Product_Number := 1;
  68.          Product_Type_Number := Product;
  69.          Production := Production_Time;
  70.       end Start;
  71.       Put_Line("Kitchen is starting production of " & Product_Name(Product_Type_Number));
  72.       loop
  73.          delay Duration(Random_Production.Random(G));
  74.          Put_Line("Kitchen cooked " & Product_Name(Product_Type_Number)
  75.                   & " number "  & Integer'Image(Product_Number));
  76.          -- Accept for storage
  77.          loop
  78.             B.Take(Product_Type_Number, Product_Number, isTaken);
  79.             if isTaken then
  80.                exit;
  81.             else
  82.                delay(5.0);
  83.          end if;
  84.       end loop;
  85.       Product_Number := Product_Number + 1;
  86.    end loop;
  87. end Producer;
  88.  
  89.    task body Consumer is
  90.       G: Random_Consumption.Generator--  random number generator (time)
  91.       G2: Random_Assembly.Generator;    --  also (assemblies)
  92.       Consumer_Nb: Consumer_Type;
  93.       Assembly_Number: Integer;
  94.       Consumption: Integer;
  95.       Assembly_Type: Integer;
  96.       Consumer_Name: constant array (1 .. Number_Of_Consumers)
  97.     of String(1 .. 9)
  98.     := ("Matthew  ", "James    ", "Anastasia");
  99.    begin
  100.       accept Start(Consumer_Number: in Consumer_Type;
  101.              Consumption_Time: in Integer) do
  102.      Random_Consumption.Reset(G);   --  ustaw generator
  103.  
  104.      Consumer_Nb := Consumer_Number;
  105.          Consumption := Consumption_Time;
  106.          
  107.       end Start;
  108.       Put_Line("Started consumer " & Consumer_Name(Consumer_Nb));
  109.       loop
  110.      delay Duration(Random_Consumption.Random(G)); --  simulate consumption
  111.          Assembly_Type := Random_Assembly.Random(G2);
  112.          -- take an assembly for consumption
  113.          Put_Line(ESC & "[93m" & Consumer_Name(Consumer_Nb) &
  114.                     " came for " &Assembly_Name(Assembly_Type) & ESC & "[0m");
  115.          select
  116.             B.Deliver(Assembly_Type, Assembly_Number);
  117.             if Assembly_Number/=0 then
  118.                Put_Line(ESC & "[96m" &Consumer_Name(Consumer_Nb) & ESC & "[0m" & ": Thank you for delicious " &
  119.                        Assembly_Name(Assembly_Type) & " number " &
  120.                           Integer'Image(Assembly_Number));
  121.             else
  122.                Put_Line(ESC & "[96m" &Consumer_Name(Consumer_Nb) & ESC & "[0m" &": That wasn't exactly what I've meant");
  123.                delay(5.0);
  124.             end if;
  125.          else
  126.             Put_Line(ESC & "[96m" &Consumer_Name(Consumer_Nb) & ESC & "[0m" &": I'm not going to wait so long");
  127.             delay(5.0);
  128.          end select;
  129.       end loop;
  130.    end Consumer;
  131.  
  132.    task body Buffer is
  133.       Assembly_Replacement: Assembly_Type := 1;
  134.       Storage_Capacity: constant Integer := 30;
  135.       type Storage_type is array (Product_Type) of Integer;
  136.       Storage: Storage_type
  137.     := (0, 0, 0, 0, 0);
  138.       Assembly_Content: array(Assembly_Type, Product_Type) of Integer
  139.     := ((1, 1, 1, 1, 1),
  140.         (0, 1, 0, 0, 1),
  141.         (1, 0, 1, 1, 0));
  142.       Max_Assembly_Content: array(Product_Type) of Integer;
  143.       Assembly_Number: array(Assembly_Type) of Integer
  144.     := (1, 1, 1);
  145.       In_Storage: Integer := 0;
  146.  
  147.       procedure Setup_Variables is
  148.       begin
  149.      for W in Product_Type loop
  150.         Max_Assembly_Content(W) := 0;
  151.         for Z in Assembly_Type loop
  152.            if Assembly_Content(Z, W) > Max_Assembly_Content(W) then
  153.           Max_Assembly_Content(W) := Assembly_Content(Z, W);
  154.            end if;
  155.         end loop;
  156.      end loop;
  157.       end Setup_Variables;
  158.  
  159.       function Can_Accept(Product: Product_Type) return Boolean is
  160.      Free: Integer;     --  free room in the storage
  161.      -- how many products are for production of arbitrary assembly
  162.      Lacking: array(Product_Type) of Integer;
  163.      -- how much room is needed in storage to produce arbitrary assembly
  164.      Lacking_room: Integer;
  165.      MP: Boolean;           --  can accept
  166.       begin
  167.          if In_Storage >= Storage_Capacity then
  168.  
  169.         return False;
  170.      end if;
  171.      -- There is free room in the storage
  172.      Free := Storage_Capacity - In_Storage;
  173.      MP := True;
  174.      for W in Product_Type loop
  175.         if Storage(W) < Max_Assembly_Content(W) then
  176.            MP := False;
  177.         end if;
  178.      end loop;
  179.      if MP then
  180.         return True;        --  storage has products for arbitrary
  181.                         --  assembly
  182.      end if;
  183.      if Integer'Max(0, Max_Assembly_Content(Product) - Storage(Product)) > 0 then
  184.         -- exactly this product lacks
  185.         return True;
  186.      end if;
  187.      Lacking_room := 1;         --  insert current product
  188.      for W in Product_Type loop
  189.         Lacking(W) := Integer'Max(0, Max_Assembly_Content(W) - Storage(W));
  190.         Lacking_room := Lacking_room + Lacking(W);
  191.      end loop;
  192.      if Free >= Lacking_room then
  193.         -- there is enough room in storage for arbitrary assembly
  194.         return True;
  195.      else
  196.         -- no room for this product
  197.         return False;
  198.      end if;
  199.       end Can_Accept;
  200.  
  201.       function Can_Deliver(Assembly: Assembly_Type) return Boolean is
  202.       begin
  203.      for W in Product_Type loop
  204.         if Storage(W) < Assembly_Content(Assembly, W) then
  205.            return False;
  206.         end if;
  207.      end loop;
  208.      return True;
  209.       end Can_Deliver;
  210.  
  211.       procedure Storage_Contents is
  212.       begin
  213.      for W in Product_Type loop
  214.         Put_Line("Products available: " & Integer'Image(Storage(W)) & " "
  215.                & Product_Name(W));
  216.      end loop;
  217.       end Storage_Contents;
  218.  
  219.    begin
  220.       Put_Line("Restaurant is open. Waiter started his work!");
  221.       Setup_Variables;
  222.       loop
  223.          select
  224.             accept Take(Product: in Product_Type; Number: in Integer; isTaken: out Boolean) do
  225.                if Can_Accept(Product) then
  226.  
  227.                   Put_Line(ESC & "[92m" & "Accepted product " & Product_Name(Product) & " number " &
  228.                              Integer'Image(Number) & ESC & "[0m");
  229.                   Storage(Product) := Storage(Product) + 1;
  230.                   In_Storage := In_Storage + 1;
  231.                   isTaken:=True;
  232.                else
  233.                   Put_Line("Rejected product " & Product_Name(Product) & " number " &
  234.                              Integer'Image(Number));
  235.                isTaken:=False;
  236.                end if;
  237.             end Take;
  238.          or
  239.             --Storage_Contents;
  240.             accept Deliver(Assembly: in Assembly_Type; Number: out Integer) do
  241.                if Can_Deliver(Assembly) then
  242.                   Put_Line(ESC & "[92m" & "Delivered meal " & Assembly_Name(Assembly) & " number " &
  243.                              Integer'Image(Assembly_Number(Assembly)) & ESC & "[0m");
  244.                   for W in Product_Type loop
  245.                      Storage(W) := Storage(W) - Assembly_Content(Assembly, W);
  246.                      In_Storage := In_Storage - Assembly_Content(Assembly, W);
  247.                   end loop;
  248.                   Number := Assembly_Number(Assembly);
  249.                   Assembly_Number(Assembly) := Assembly_Number(Assembly) + 1;
  250.                else
  251.                   Put_Line("May I offer you something different?");
  252.                   while ((Assembly_Replacement-1)<3) loop
  253.                      if Can_Deliver(Assembly_Replacement) then
  254.                         Put_Line("Let me serve you " & Assembly_Name(Assembly_Replacement) & " number " &
  255.                                    Integer'Image(Assembly_Number(Assembly_Replacement)));
  256.                         for W in Product_Type loop
  257.                            Storage(W) := Storage(W) - Assembly_Content(Assembly_Replacement, W);
  258.                            In_Storage := In_Storage - Assembly_Content(Assembly_Replacement, W);
  259.                         end loop;
  260.                         Number := 0;
  261.                         Assembly_Number(Assembly_Replacement) := Assembly_Number(Assembly_Replacement) + 1;
  262.                         return;
  263.                      end if;
  264.                      Assembly_Replacement := Assembly_Replacement +1;
  265.  
  266.                   end loop;
  267.                   Assembly_Replacement:=1;
  268.                   Put_Line("Lacking products for replacement products. We're so busy we don't serve anything.");
  269.                   Number := 0;
  270.                end if;
  271.             end Deliver;
  272.          end select;
  273.     Storage_Contents;
  274.       end loop;
  275.    end Buffer;
  276.  
  277. begin
  278.      
  279.    for I in 1 .. Number_Of_Products loop
  280.       P(I).Start(I, 10);
  281.    end loop;
  282.    for J in 1 .. Number_Of_Consumers loop
  283.       K(J).Start(J,12);
  284.       end loop;
  285.      
  286. end Simulation;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement