<<>> <> <> <> <> <<>> DIRECTORY G2dBasic, G3dBasic, G3dNats, Real, Rope; G3dNatsImpl: CEDAR MONITOR IMPORTS G2dBasic, Real EXPORTS G3dNats ~ BEGIN <> ROPE: TYPE ~ Rope.ROPE; IntegerPairSequence: TYPE ~ G2dBasic.IntegerPairSequence; IntegerPairSequenceRep: TYPE ~ G2dBasic.IntegerPairSequenceRep; NatSequence: TYPE ~ G2dBasic.NatSequence; NatSequenceRep: TYPE ~ G2dBasic.NatSequenceRep; BoolSequence: TYPE ~ G3dBasic.BoolSequence; BoolSequenceRep: TYPE ~ G3dBasic.BoolSequenceRep; NatTable: TYPE ~ G3dNats.NatTable; NatTableRep: TYPE ~ G3dNats.NatTableRep; Error: PUBLIC SIGNAL [reason: ROPE] = CODE; <> NewNatSequence3: PUBLIC PROC [v0, v1, v2: INT] RETURNS [nats: NatSequence] ~ { nats ¬ NEW[NatSequenceRep[3]]; nats.length ¬ 3; nats[0] ¬ v0; nats[1] ¬ v1; nats[2] ¬ v2; }; EqualNatSequences: PUBLIC PROC [s1, s2: NatSequence] RETURNS [BOOL] ~ { <> match: BoolSequence ¬ NEW[BoolSequenceRep[s1.length]]; match.length ¬ s1.length; IF s1=NIL OR s2=NIL THEN RETURN [FALSE]; IF s1.length # s2.length THEN RETURN [FALSE]; FOR i: INT IN [0 .. s1.length) DO match[i] ¬ FALSE; FOR j: INT IN [0 .. s2.length) DO IF s2[j] = s1[i] THEN { match[i] ¬ TRUE; EXIT; }; ENDLOOP; ENDLOOP; FOR i: INT IN [0 .. match.length) DO IF NOT match[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; GetCommonElementInNatSequences: PUBLIC PROC [n1, n2: NatSequence] RETURNS [INT ¬ -1] ~ { <> IF n1=NIL OR n2=NIL THEN RETURN; FOR i: INT IN [0 .. n1.length) DO FOR j: INT IN [0 .. n2.length) DO IF n1[i] = n2[j] THEN RETURN [n1[i]]; ENDLOOP; ENDLOOP; }; GetNatSequenceIndex: PUBLIC PROC [nats: NatSequence, nat: NAT] RETURNS [INT ¬ -1] ~ { <> IF nats=NIL THEN RETURN; FOR i: INT IN [0 .. nats.length) DO IF nats[i] = nat THEN RETURN[i]; ENDLOOP; }; ReplaceNatInSequence: PUBLIC PROC[n: NatSequence, old, new: NAT]RETURNS[r: NatSequence]~{ r ¬ NIL; IF n=NIL THEN RETURN; FOR i: INT IN [0 .. n.length) DO IF n[i] # old THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]] ELSE r ¬ G2dBasic.AddToNatSequence[r, new]; ENDLOOP; }; RemoveNatInSequence: PUBLIC PROC[n: NatSequence, old: NAT] RETURNS [r: NatSequence ¬ NIL ]~{ IF n=NIL THEN RETURN; FOR i: INT IN [0 .. n.length) DO IF n[i] # old THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]] ENDLOOP; }; GetUniqueElement: PUBLIC PROC [ns: NatSequence] RETURNS [unique: INT ¬ -1] ~ { <> IF ns=NIL THEN RETURN; FOR i: INT IN [0 .. ns.length) DO repeat: BOOL ¬ FALSE; FOR j: INT IN [0 .. ns.length) DO IF (i#j) AND (ns[i]=ns[j]) THEN repeat¬TRUE; ENDLOOP; IF NOT repeat THEN IF unique < 0 THEN unique ¬ ns[i] ELSE Error["no single unique element"] ENDLOOP; }; GetRepeatedElement: PUBLIC PROC [ns: NatSequence] RETURNS [INT ¬ -1] ~ { IF ns=NIL THEN RETURN; FOR i: INT IN [0 .. ns.length) DO FOR j: INT IN [0 .. ns.length) DO IF (i#j) AND (ns[i]=ns[j]) THEN RETURN[ns[i]]; ENDLOOP; ENDLOOP; }; GetElementNotShared: PUBLIC PROC [v: NAT, ns: NatSequence] RETURNS [unique: INT ¬ -1] ~ { <> IF ns=NIL THEN RETURN; FOR i: INT IN [0 .. ns.length) DO IF ns[i] # v THEN IF unique < 0 THEN unique ¬ ns[i] ELSE Error["repeated unique vertex"]; ENDLOOP; }; NatInSequence: PUBLIC PROC [nat: NAT, seq: NatSequence] RETURNS [BOOL] ~ { <> IF seq=NIL THEN RETURN [FALSE]; FOR i: INT IN [0 .. seq.length) DO IF seq[i]=nat THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; NatSequenceLength: PUBLIC PROC [seq: NatSequence] RETURNS [INT] ~ { IF seq = NIL THEN RETURN[0] ELSE RETURN [seq.length]; }; <> CopyNatTable: PUBLIC PROC [nats: NatTable] RETURNS [NatTable] ~ { copy: NatTable ¬ NIL; IF nats # NIL THEN { copy ¬ NEW[NatTableRep[nats.length]]; copy.length ¬ nats.length; FOR n: NAT IN [0..nats.length) DO copy[n] ¬ nats[n]; ENDLOOP; }; RETURN[copy]; }; AddToNatTable: PUBLIC PROC [nats: NatTable, nat: NatSequence] RETURNS [NatTable] ~ { IF nats = NIL THEN nats ¬ NEW[NatTableRep[1]]; IF nats.length = nats.maxLength THEN nats ¬ LengthenNatTable[nats]; nats[nats.length] ¬ nat; nats.length ¬ nats.length+1; RETURN[nats]; }; <<>> LengthenNatTable: PUBLIC PROC [nats: NatTable, amount: REAL ¬ 1.3] RETURNS [new: NatTable] ~ { newLength: CARDINAL ¬ Real.Ceiling[amount*nats.maxLength]; newLength ¬ MAX[newLength, 3]; new ¬ NEW[NatTableRep[newLength]]; FOR i: NAT IN [0..nats.length) DO new[i] ¬ nats[i]; ENDLOOP; new.length ¬ nats.length; }; <> scratchNats: ARRAY [0..10) OF NatSequence ¬ ALL[NIL]; scratchIntegerPairs: ARRAY [0..10) OF IntegerPairSequence ¬ ALL[NIL]; ObtainScratchNats: PUBLIC ENTRY PROC [length: INTEGER] RETURNS [NatSequence] ~ { FOR i: NAT IN [0..10) DO scratch: NatSequence ¬ scratchNats[i]; IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP; scratchNats[i] ¬ NIL; RETURN[scratch]; ENDLOOP; RETURN[NEW[NatSequenceRep[length]]]; }; ReleaseScratchNats: PUBLIC ENTRY PROC [scratch: NatSequence] ~ { FOR i: INTEGER IN [0..10) DO IF scratchNats[i] # NIL AND scratch.maxLength <= scratchNats[i].maxLength THEN LOOP; scratchNats[i] ¬ scratch; RETURN; ENDLOOP; }; ObtainScratchIntegerPairs: PUBLIC ENTRY PROC [length: INTEGER] RETURNS [IntegerPairSequence] ~ { FOR i: NAT IN [0..10) DO scratch: IntegerPairSequence ¬ scratchIntegerPairs[i]; IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP; scratchIntegerPairs[i] ¬ NIL; RETURN[scratch]; ENDLOOP; RETURN[NEW[IntegerPairSequenceRep[length]]]; }; ReleaseScratchIntegerPairs: PUBLIC ENTRY PROC [scratch: IntegerPairSequence] ~ { FOR i: INTEGER IN [0..10) DO IF scratchIntegerPairs[i] # NIL AND scratch.maxLength <= scratchIntegerPairs[i].maxLength THEN LOOP; scratchIntegerPairs[i] ¬ scratch; RETURN; ENDLOOP; }; END.