LichenIntBasicsImpl.Mesa
Last tweaked by Mike Spreitzer on August 5, 1988 11:22:12 am PDT
DIRECTORY AbSets, IO, LichenIntBasics, SetBasics;
LichenIntBasicsImpl: CEDAR PROGRAM
IMPORTS IO, LichenIntBasics, SetBasics
EXPORTS LichenIntBasics
=
BEGIN OPEN Sets:AbSets, LichenIntBasics;
Range2Div: PUBLIC PROC [r: Range2, t, f: Int2] RETURNS [rr: Range2] = {
rr ← [
X: [
min: CeilDiv[r[X].min-f[X], t[X]],
maxPlusOne: FloorDiv[r[X].maxPlusOne-1-f[X], t[X]] + 1],
Y: [
min: CeilDiv[r[Y].min-f[Y], t[Y]],
maxPlusOne: FloorDiv[r[Y].maxPlusOne-1-f[Y], t[Y]] + 1]];
};
Range1Div: PUBLIC PROC [r: Range, t, f: NATURAL] RETURNS [rr: Range] = {
rr ← [
min: CeilDiv[r.min-f, t],
maxPlusOne: FloorDiv[r.maxPlusOne-1-f, t] + 1];
};
Range2MulA: PUBLIC PROC [r: Range2, t, f: Int2] RETURNS [rr: Range2] = {
rr ← [
X: [
min: r[X].min*t[X] + f[X],
maxPlusOne: (r[X].maxPlusOne-1)*t[X] + 1 + f[X]],
Y: [
min: r[Y].min*t[Y] + f[Y],
maxPlusOne: (r[Y].maxPlusOne-1)*t[Y] + 1 + f[Y]]];
};
Range2MulB: PUBLIC PROC [r: Range2, t, f: Int2] RETURNS [rr: Range2] = {
rr ← [
X: [
min: r[X].min*t[X] + f[X],
maxPlusOne: r[X].maxPlusOne*t[X] + f[X]],
Y: [
min: r[Y].min*t[Y] + f[Y],
maxPlusOne: r[Y].maxPlusOne*t[Y] + f[Y]]];
};
Range1MulB: PUBLIC PROC [r: Range, t, f: NATURAL] RETURNS [rr: Range] = {
rr ← [
min: r.min*t + f,
maxPlusOne: r.maxPlusOne*t + f];
};
int2s: PUBLIC SetBasics.Space ← NEW [SetBasics.SpacePrivate ← [
Contains: SetBasics.ints.Contains,
Equal: SetBasics.ints.Equal,
Print: Int2sPrint,
AHash: SetBasics.ints.AHash,
ACompare: Int2sCompare,
name: "int2s"]];
Int2sPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
i: Int2 ~ VI2[v];
to.PutF["<%g,%g>", [integer[i[X]]], [integer[i[Y]]]];
RETURN};
Int2sCompare: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [c: SetBasics.TotalComparison] ~ {
i1: Int2 ~ VI2[v1];
i2: Int2 ~ VI2[v2];
IF (c ← SetBasics.CompareIntI[MIN[i1[X], i1[Y]], MIN[i2[X], i2[Y]]])#equal THEN RETURN;
c ← SetBasics.CompareIntI[MAX[i1[X], i1[Y]], MAX[i2[X], i2[Y]]];
RETURN};
xfmSpace: PUBLIC SetBasics.Space ← NEW [SetBasics.SpacePrivate ← [
Contains: XfmsContains,
Equal: XfmsEqual,
Print: XfmsPrint,
AHash: SetBasics.ints.AHash,
ACompare: SetBasics.ints.ACompare,
name: "xfms"]];
XfmsContains: PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
IF v.ra#NIL THEN RETURN [FALSE];
IF v.i<0 THEN RETURN [FALSE];
IF v.i > XfmV[[TRUE, ALL[TRUE]]].i THEN RETURN [FALSE];
RETURN [TRUE]};
XfmsEqual: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [BOOL] ~ {
x1: Transform ~ VXfm[v1];
x2: Transform ~ VXfm[v2];
RETURN [x1=x2]};
XfmsPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
x: Transform ~ VXfm[v];
to.PutRope[FormatTransform[x]];
RETURN};
XfmName: TYPE ~ ARRAY --transpose--BOOL OF ARRAY --mx--BOOL OF ARRAY --my--BOOL OF ROPE;
xfmName: REF XfmName ← NEW [XfmName ← [
FALSE: [
FALSE: ["Id", "MirrorY"],
TRUE: ["MirrorX", "Rot180"]],
TRUE: [
FALSE: ["Transpose", "RotRight"],
TRUE: ["RotLeft", "Posetrans"]] ]];
FormatTransform: PUBLIC PROC [x: Transform] RETURNS [ROPE] ~ {
RETURN [xfmName[x.transpose][x.mirror[X]][x.mirror[Y]]]};
XfmFrom4: PUBLIC PROC [dxdx, dxdy, dydx, dydy: INT] RETURNS [Transform] ~ {
IF dxdy=0 AND dydx=0 THEN
IF dxdx=1 THEN
IF dydy=1 THEN RETURN [[FALSE, [FALSE, FALSE]]]
ELSE IF dydy=-1 THEN RETURN [[FALSE, [FALSE, TRUE]]]
ELSE ERROR
ELSE IF dxdx=-1 THEN
IF dydy=1 THEN RETURN [[FALSE, [TRUE, FALSE]]]
ELSE IF dydy=-1 THEN RETURN [[FALSE, [TRUE, TRUE]]]
ELSE ERROR
ELSE ERROR
ELSE IF dxdx=0 AND dydy=0 THEN
IF dxdy=1 THEN
IF dydx=1 THEN RETURN [[TRUE, [FALSE, FALSE]]]
ELSE IF dydx=-1 THEN RETURN [[TRUE, [FALSE, TRUE]]]
ELSE ERROR
ELSE IF dxdy=-1 THEN
IF dydx=1 THEN RETURN [[TRUE, [TRUE, FALSE]]]
ELSE IF dydx=-1 THEN RETURN [[TRUE, [TRUE, TRUE]]]
ELSE ERROR
ELSE ERROR
ELSE ERROR};
Compose: PUBLIC PROC [first, then: Transform] RETURNS [Transform] ~ {
mid: Transform ~ Invert[[then.transpose, first.mirror]];
RETURN [[mid.transpose#first.transpose, [mid.mirror[X]#then.mirror[X], mid.mirror[Y]#then.mirror[Y]] ]]};
Invert: PUBLIC PROC [xfm: Transform] RETURNS [Transform] ~ {
IF xfm.transpose THEN RETURN [[TRUE, [xfm.mirror[Y], xfm.mirror[X]] ]];
RETURN [xfm]};
InvertXO: PUBLIC PROC [xfm: Transform, offset: Int2] RETURNS [Transform, Int2] ~ {
xfm ← Invert[xfm];
offset ← Neg[TransformVector[xfm, offset]];
RETURN [xfm, offset]};
TransformSize: PUBLIC PROC [xfm: Transform, size: Int2] RETURNS [Int2] ~ {
RETURN [IF xfm.transpose THEN [size[Y], size[X]] ELSE size]};
TransformVector: PUBLIC PROC [xfm: Transform, vec: Int2] RETURNS [Int2] ~ {
ans: Int2 ← IF xfm.transpose THEN [vec[Y], vec[X]] ELSE vec;
IF xfm.mirror[X] THEN ans[X] ← -ans[X];
IF xfm.mirror[Y] THEN ans[Y] ← -ans[Y];
RETURN [ans]};
TransformPos: PUBLIC PROC [xfm: Transform, vec, size: Int2] RETURNS [Int2] ~ {
ans: Int2 ← IF xfm.transpose THEN [vec[Y], vec[X]] ELSE vec;
IF xfm.mirror[X] THEN ans[X] ← size[X]-1 - ans[X];
IF xfm.mirror[Y] THEN ans[Y] ← size[Y]-1 - ans[Y];
RETURN [ans]};
TransOffPos: PUBLIC PROC [xfm: Transform, offset, pos: Int2] RETURNS [Int2]
~ {RETURN Add[offset, TransformVector[xfm, pos]]};
TransOffRange2: PUBLIC PROC [xfm: Transform, offset: Int2, r: Range2] RETURNS [Range2] ~ {
p1: Int2 ~ TransOffPos[xfm, offset, Range2Min[r]];
p2: Int2 ~ TransOffPos[xfm, offset, [r[X].maxPlusOne, r[Y].maxPlusOne]];
RETURN [[
X: [MIN[p1[X], p2[X]], MAX[p1[X], p2[X]]],
Y: [MIN[p1[Y], p2[Y]], MAX[p1[Y], p2[Y]]] ]]};
FloorDiv: PROC [num, den: INT] RETURNS [INT]
~ INLINE {RETURN [num/den]};
CeilDiv: PROC [num, den: INT] RETURNS [INT]
~ INLINE {RETURN [-((-num)/den)]};
END.