SimSet begin boolean Debugging = true; class BinTreeNode(Key); value Key; text Key; virtual: procedure DumpData; begin ref(BinTreeNode) Left, Right; procedure Dump(L); integer L; begin integer I; if Right =/= none then Right.Dump(L+1); for I := 0 step 1 until L do OutChar('.'); OutText("Key=" & Key & ":"); DumpData; OutImage; if Left =/= none then Left.Dump(L+1); end Dump; procedure DumpData;; ref(BinTreeNode) procedure Find(K); text K; begin if Key = K then begin Find :- this BinTreeNode; end else if KKey and Right=/=none then begin Find :- Right.Find(K); end if; end Find; ref(BinTreeNode) procedure Into(P); name P; ref(BinTreeNode) P; begin if P == none then begin Into :- P :- this BinTreeNode; end else if Key = P.Key then begin Into :- P; end else if Key < P.Key then begin Into :- Into(P.Left); end else begin Into :- Into(P.Right); end if; end Into; end BinTreeNode; Link class Relation(P, Steps); ref(Person) P; integer Steps; begin end Relation; BinTreeNode class Person; begin ref(Head) Ancestors; procedure AddAncestor(P, L); ref(Person) P; integer L; begin new Relation(P,L).Into(Ancestors); end AddAncestor; procedure DumpData; begin ref(Relation) Rx; Rx :- Ancestors.First; while Rx =/= none do begin OutText(" (" & Rx.P.Key & ","); OutInt(Rx.Steps,0); OutText(")"); Rx :- Rx.Suc; end while; end DumpData; boolean procedure IsDescendant(P); ref(Person) P; begin comment Is `this Person' a descendant of `P'? ; ref(Relation) Rx; boolean IsD; if P =/= this Person then begin Rx :- Ancestors.First; while Rx=/=none and not IsD do begin if Rx.P.IsDescendant(P) then IsDescendant := IsD := true; Rx :- Rx.Suc; end while; end else IsDescendant := IsD := true; if Debugging then begin OutText("Debugging: " & Key & " is "); if not IsD then OutText("not "); OutText("a descendant of " & P.Key); OutImage; end if; end IsDescendant; integer procedure Level(Px); ref(Person) Px; begin comment How many levels must we go back to get to `Px' (whom we know --"-- is an ancestor)? If several paths, choose the shortes. ; ref(Relation) Rx; integer Lmin, Lx; if Px =/= this Person then begin Rx :- Ancestors.First; Lmin := -1; while Rx =/= none do begin Lx := Rx.P.Level(Px); if Lx >= 0 then begin if Debugging then begin OutText("Debug> There are "); OutInt(Lx, 0); OutText("+"); OutInt(Rx.Steps, 0); OutText(" = "); OutInt(Lx + Rx.Steps, 0); OutText(" generations from " & Key & " via " & Rx.P.Key); OutText(" to " & Px.Key); OutImage; end if; Lx := Lx + Rx.Steps; if Lmin<0 or LxCR.Level then false else Removed 'E' do begin if Debugging then begin OutText("Debug: Read a "); OutChar(C); OutText("-line: " & Image.Strip); OutImage; end if; if C = '#' then begin end else if C = 'R' then begin ref(Person) P1, P2; text N1, N2; integer Lev; N1 :- Image.Sub(2,5); N2 :- Image.Sub(7,5); SetPos(12); Lev := InInt; P1 :- new Person(N1).Into(Root); P2 :- new Person(N2).Into(Root); P1.AddAncestor(P2, Lev); if Debugging then begin OutText("Dump: Family tree:"); OutImage; Root.Dump(0); end if; end else begin ref(Person) P1, P2; text N1, N2; N1 :- Image.Sub(2,5); N2 :- Image.Sub(7,5); if Root =/= none then begin P1 :- Root.Find(N1); P2 :- Root.Find(N2); end if; OutF.OutText(N1 & " and " & N2 & " are "); FindCousins(P1,P2).Print(OutF); OutF.OutImage; end if; InImage; C := InChar; end while; OutF.Close; Close; end inspect; end