with Linda; use Linda; package Matrix is type Vector_Type is array (1..3) of integer; function "*" (Left, Right: Vector_Type) return integer; type Matrix_Type is array (1..3) of Vector_Type; function "*" (Left, Right: Matrix_Type) return Matrix_Type; procedure Transpose (A: in Matrix_Type; B: out Matrix_Type); procedure print (M: Matrix_Type); private type Vector_Parameter_Type is new Parameter_Type with record V: Vector_Type; end record; function "=" (Left, Right: Vector_Parameter_Type) return boolean; end Matrix;
with Matrix; use Matrix; procedure Test is begin print ( Matrix_Type'((1, 2, 3), (4, 5, 6), (7, 8, 9)) * Matrix_Type'((2, 3, 4), (5, 6, 7), (8, 9, 10)) ); end Test;
-- multipliziere zwei Matrizen und gebe das Ergebnis zurueck function "*" (Left, Right: Matrix_Type) return Matrix_Type is B, C: Matrix_Type; T : Tuple_Type; It : Iterator_Type; i, j: natural; -- Ein Inner_Producer harrt darauf, innere Produkte zu bilden task type Inner_Producer; -- Hier kann man beliebig viele Produzenten erzeugen Producers: array (1..5) of Inner_Producer; task body Inner_Producer is T: Tuple_Type; Element: natural; i, j: natural; V1, V2: Vector_Type; begin loop -- Input ("N", Element: integer) Empty (T); Add (T, Char_Parameter_Type'(false, 'N')); Add (T, Int_Parameter_Type'(true, 0)); Input (T); Element := Int_Parameter_Type (Value (Succ (First (T)))).Int; -- Output ("N", Element+1) Empty (T); Add (T, Char_Parameter_Type'(false, 'N')); Add (T, Int_Parameter_Type'(false, Element + 1)); Output (T); exit when Element > 3 * 3; -- Zeile und Spalte ermitteln i := (Element - 1) / 3 + 1; j := (Element - 1) mod 3 + 1; -- Read ("A", i, V1: Vector) Empty (T); Add (T, Char_Parameter_Type'(false, 'A')); Add (T, Int_Parameter_Type'(false, i)); Add (T, Vector_Parameter_Type'(true, (others => 0))); Read (T); V1 := Vector_Parameter_Type (Value (Succ (Succ (First (T))))).V; -- Read ("B", j, Vector) Empty (T); Add (T, Char_Parameter_Type'(false, 'B')); Add (T, Int_Parameter_Type'(false, j)); Add (T, Vector_Parameter_Type'(true, (others => 0))); Read (T); V2 := Vector_Parameter_Type (Value (Succ (Succ (First (T))))).V; -- Output ("C", i, j, V1 * V2) Empty (T); Add (T, Char_Parameter_Type'(false, 'C')); Add (T, Int_Parameter_Type'(false, i)); Add (T, Int_Parameter_Type'(false, j)); Add (T, Int_Parameter_Type'(false, V1 * V2)); Output (T); end loop; end Inner_Producer; begin -- Die zweite Matrix transponieren, um Spaltenvektoren zu erhalten Transpose (Right, B); -- Die Vektoren der beiden Matrizen ausgeben for i in 1..3 loop -- Output ("A", i, Zeilenvektor) Empty (T); Add (T, Char_Parameter_Type'(false, 'A')); Add (T, Int_Parameter_Type'(false, i)); Add (T, Vector_Parameter_Type'(false, Left (i))); Output (T); end loop; for i in 1..3 loop -- Output ("B", i, Spaltenvektor) Empty (T); Add (T, Char_Parameter_Type'(false, 'B')); Add (T, Int_Parameter_Type'(false, i)); Add (T, Vector_Parameter_Type'(false, B (i))); Output (T); end loop; -- Output ("N", 1) Empty (T); Add (T, Char_Parameter_Type'(false, 'N')); Add (T, Int_Parameter_Type'(false, 1)); Output (T); -- Ergebnisse sammeln for k in 1..3*3 loop -- Input ("C", i: integer, j: integer, c) Empty (T); Add (T, Char_Parameter_Type'(false, 'C')); Add (T, Int_Parameter_Type'(true, 0)): Add (T, Int_Parameter_Type'(true, 0)); Add (T, Int_Parameter_Type'(true, 0)); Input (T); It := Succ (First (T)); i := Int_Parameter_Type (Value (It)).Int; It := Succ (It); j := Int_Parameter_Type (Value (It)).Int; -- C (i) (j) := c It := Succ (It); C (i) (j) := Int_Parameter_Type (Value (It)).Int; end loop; return C; end "*";
$ test 36 42 48 81 96 111 126 150 174 $ _