(* Find a solution to the stable marriage problem. n men and n women state their preferences of partners. Find n pairs such that no man would prefer to be married to another woman who would also prefer him to her partner. A set of pairs is called stable, if no such cases exist. [see also Comm. ACM 14, 7, 486-92 (July 71)]. *) MODULE marriage; FROM InOut IMPORT WriteString, Write, WriteLn, WriteCard, ReadCard; CONST n = 8; TYPE man = [1..n]; woman = [1..n]; rank = [1..n]; VAR m: man; w: woman; r: rank; wmr: ARRAY man,rank OF woman; mwr: ARRAY woman,rank OF man; rmw: ARRAY man,woman OF rank; rwm: ARRAY woman,man OF rank; x: ARRAY man OF woman; y: ARRAY woman OF man; single: ARRAY woman OF BOOLEAN; PROCEDURE print; VAR m: man; rm,rw: CARDINAL; BEGIN rm := 0; rw := 0; FOR m := 1 TO n DO WriteCard(x[m],4); rm := rm + rmw[m,x[m]]; rw := rw + rwm[x[m],m] END; WriteCard(rm,8); WriteCard(rw,4); WriteLn END print; PROCEDURE try(m: man); VAR r: rank; w: woman; PROCEDURE stable(): BOOLEAN; VAR pm: man; pw: woman; i,lim: rank; s: BOOLEAN; BEGIN s := TRUE; i := 1; WHILE (i < r) AND s DO pw := wmr[m,i]; INC(i); IF NOT single[pw] THEN s := rwm[pw,m] > rwm[pw,y[pw]] END; END; i := 1; lim := rwm[w,m]; WHILE (i < lim) AND s DO pm := mwr[w,i]; INC(i); IF pm < m THEN s := rmw[pm,w] > rmw[pm,x[pm]] END; END; RETURN s END stable; BEGIN FOR r := 1 TO n DO w := wmr[m,r]; IF single[w] THEN IF stable() THEN x[m] := w; y[w] := m; single[w] := FALSE; IF m < n THEN try(m+1) ELSE print END; single[w] := TRUE END END END END try; BEGIN Write('1'); WriteLn; FOR m := 1 TO n DO FOR r := 1 TO n DO WriteString('Enter> '); ReadCard(wmr[m,r]); rmw[m,wmr[m,r]] := r; WriteLn; END END; FOR w := 1 TO n DO FOR r := 1 TO n DO WriteString('Enter2> '); ReadCard(mwr[w,r]); rwm[w,mwr[w,r]] := r; WriteLn; END END; FOR w := 1 TO n DO single[w] := TRUE END; try(1) END marriage. (* 5 7 1 2 6 8 4 3 2 3 7 5 4 1 8 6 8 5 1 4 6 2 3 7 3 2 7 4 1 6 8 5 7 2 5 1 3 6 8 4 1 6 7 5 8 4 2 3 2 5 7 6 3 4 8 1 3 8 4 5 7 2 6 1 5 3 7 6 1 2 8 4 8 6 3 5 7 2 1 4 1 5 6 2 4 8 7 3 8 7 3 2 4 1 5 6 6 4 7 3 8 1 2 5 2 8 5 4 6 3 7 1 7 5 2 1 8 6 4 3 7 4 1 5 2 3 6 8 *)