Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.46 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.Integer_Text_IO;
  7. with Ada.Numerics.Discrete_Random;
  8.  
  9.  
  10. procedure Lab1 is
  11. Number_Of_Products: constant Integer := 5;
  12. Number_Of_Assemblies: constant Integer := 3;
  13. Number_Of_Consumers: constant Integer := 2;
  14. subtype Product_Type is Integer range 1 .. Number_Of_Products;
  15. subtype Assembly_Type is Integer range 1 .. Number_Of_Assemblies;
  16. subtype Consumer_Type is Integer range 1 .. Number_Of_Consumers;
  17. Icecream: constant array (Product_Type) of String(1 .. 10)
  18. := ("Vanilla ", "Strawberry", "Green Tea ", "Cookies ", "Pistachio ");
  19. Assembly_Name: constant array (Assembly_Type) of String(1 .. 11)
  20. := ("Milky World", "Ice Masters", "Cows & Ice ");
  21. package Random_Assembly is new
  22. type My_Str is new String(1 ..256);
  23.  
  24. -- Producer produces determined product
  25. task type Producer is
  26.  
  27. -- Consumer gets an arbitrary assembly of several products from the buffer
  28. task type Consumer is
  29.  
  30. -- In the Buffer, products are assemblied into an assembly
  31. task type Buffer is
  32.  
  33. P: array ( 1 .. Number_Of_Products ) of Producer;
  34. K: array ( 1 .. Number_Of_Consumers ) of Consumer;
  35. B: Buffer;
  36.  
  37. task body Producer is
  38. subtype Production_Time_Range is Integer range 3 .. 6;
  39. package Random_Production is new
  40. Ada.Numerics.Discrete_Random(Production_Time_Range);
  41. G: Random_Production.Generator; -- generator liczb losowych
  42. Product_Type_Number: Integer;
  43. Product_Number: Integer;
  44. Production: Integer;
  45. Taken: Boolean;
  46. begin
  47. accept Start(Product: in Product_Type; Production_Time: in Integer) do
  48. Random_Production.Reset(G); -- start random number generator
  49. Product_Number := 1;
  50. Product_Type_Number := Product;
  51. Production := Production_Time;
  52. end Start;
  53. Put_Line("Started production of " & Icecream(Product_Type_Number));
  54. loop
  55. delay Duration(Random_Production.Random(G)); -- symuluj produkcję
  56. Put_Line("Produced product " & Icecream(Product_Type_Number)
  57. & " number " & Integer'Image(Product_Number));
  58. -- Accept for storage
  59. loop
  60. B.Take(Product_Type_Number, Product_Number, Taken);
  61. exit when Taken;
  62. delay Duration(Random_Production.Random(G));
  63. end loop;
  64. Product_Number := Product_Number + 1;
  65.  
  66.  
  67. end loop;
  68. end Producer;
  69.  
  70. task body Consumer is
  71.  
  72. task body Buffer is
  73. Storage_Capacity: constant Integer := 30;
  74. type Storage_type is array (Product_Type) of Integer;
  75. Storage: Storage_type
  76. := (0, 0, 0, 0, 0);
  77. Assembly_Content: array(Assembly_Type, Product_Type) of Integer
  78. := ((2, 1, 2, 1, 2),
  79. (2, 2, 0, 1, 0),
  80. (1, 1, 2, 0, 1));
  81. Max_Assembly_Content: array(Product_Type) of Integer;
  82. Assembly_Number: array(Assembly_Type) of Integer
  83. := (1, 1, 1);
  84. In_Storage: Integer := 0;
  85. Taken: Boolean := False;
  86.  
  87. procedure Setup_Variables is
  88. begin
  89. for W in Product_Type loop
  90. Max_Assembly_Content(W) := 0;
  91. for Z in Assembly_Type loop
  92. if Assembly_Content(Z, W) > Max_Assembly_Content(W) then
  93. Max_Assembly_Content(W) := Assembly_Content(Z, W);
  94. end if;
  95. end loop;
  96. end loop;
  97. end Setup_Variables;
  98.  
  99. function Can_Accept(Product: Product_Type) return Boolean is
  100. Free: Integer; -- free room in the storage
  101. -- how many products are for production of arbitrary assembly
  102. Lacking: array(Product_Type) of Integer;
  103. -- how much room is needed in storage to produce arbitrary assembly
  104. Lacking_room: Integer;
  105. MP: Boolean; -- can accept
  106. begin
  107. if In_Storage >= Storage_Capacity then
  108. return False;
  109. end if;
  110. -- There is free room in the storage
  111. Free := Storage_Capacity - In_Storage;
  112. MP := True;
  113. for W in Product_Type loop
  114. if Storage(W) < Max_Assembly_Content(W) then
  115. MP := False;
  116. end if;
  117. end loop;
  118. if MP then
  119. return True; -- storage has products for arbitrary
  120. -- assembly
  121. end if;
  122. if Integer'Max(0, Max_Assembly_Content(Product) - Storage(Product)) > 0 then
  123. -- exactly this product lacks
  124. return True;
  125. end if;
  126. Lacking_room := 1; -- insert current product
  127. for W in Product_Type loop
  128. Lacking(W) := Integer'Max(0, Max_Assembly_Content(W) - Storage(W));
  129. Lacking_room := Lacking_room + Lacking(W);
  130. end loop;
  131. if Free >= Lacking_room then
  132. -- there is enough room in storage for arbitrary assembly
  133. return True;
  134. else
  135. -- no room for this product
  136. return False;
  137. end if;
  138. end Can_Accept;
  139.  
  140. function Can_Deliver(Assembly: Assembly_Type) return Boolean is
  141. begin
  142. for W in Product_Type loop
  143. if Storage(W) < Assembly_Content(Assembly, W) then
  144. return False;
  145. end if;
  146. end loop;
  147. return True;
  148. end Can_Deliver;
  149.  
  150. procedure Storage_Contents is
  151. begin
  152. for W in Product_Type loop
  153. Put_Line("Storage contents: " & Integer'Image(Storage(W)) & " "
  154. & Icecream(W));
  155. end loop;
  156. end Storage_Contents;
  157.  
  158. begin
  159. Put_Line("Buffer started");
  160. Setup_Variables;
  161. loop
  162. select
  163. accept Take(Product: in Product_Type; Number: in Integer; Taken: out Boolean) do
  164. Taken := False;
  165. if Can_Accept(Product) then
  166. Put_Line("Accepted product " & Icecream(Product) & " number " &
  167. Integer'Image(Number));
  168. Storage(Product) := Storage(Product) + 1;
  169. In_Storage := In_Storage + 1;
  170. Taken := True;
  171. else
  172. Put_Line("Rejected product " & Icecream(Product) & " number " &
  173. Integer'Image(Number));
  174. end if;
  175. end Take;
  176. Storage_Contents;
  177. else
  178. accept Deliver(Assembly: in Assembly_Type; Number: out Integer) do
  179. if Can_Deliver(Assembly) then
  180. Put_Line("Delivered assembly " & Assembly_Name(Assembly) & " number " &
  181. Integer'Image(Assembly_Number(Assembly)));
  182. for W in Product_Type loop
  183. Storage(W) := Storage(W) - Assembly_Content(Assembly, W);
  184. In_Storage := In_Storage - Assembly_Content(Assembly, W);
  185. end loop;
  186. Number := Assembly_Number(Assembly);
  187. Assembly_Number(Assembly) := Assembly_Number(Assembly) + 1;
  188.  
  189. else
  190. Put_Line("Lacking products for assembly " & Assembly_Name(Assembly));
  191. Number := 0;
  192. end if;
  193. end Deliver;
  194. Storage_Contents;
  195.  
  196. end select;
  197.  
  198. end loop;
  199. end Buffer;
  200.  
  201. begin
  202. for I in 1 .. Number_Of_Products loop
  203. for J in 1 .. Number_Of_Consumers loop
  204. end Lab1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement