StdPairCollections2.Mesa
Last tweaked by Mike Spreitzer on October 19, 1987 1:47:38 pm PDT
DIRECTORY Atom, Basics, Collections, IntFunctions, PairCollections, List;
StdPairCollections2: CEDAR PROGRAM
IMPORTS Collections, IntFunctions, PairCollections, List
EXPORTS PairCollections
=
BEGIN OPEN IntFns:IntFunctions, Colls:Collections, IntFunctions, Collections, PairCollections;
NCreateSingleton: PUBLIC PROC [elt: Pair, spaces: SpacePair] RETURNS [ConstPairColl]
~ {RETURN [[[[GetSingletonClass[spaces], NEW [Pair ← elt]]]]]};
MakeSingletonClass: PROC [spaces: SpacePair] RETURNS [class: PairCollClass] ~ {
class ← CreateClass[
cp: [
HasPair: SingletonHasPair,
Scan: ScanSingleton,
Size: SingletonSize,
Spaces: IF spaces[left]=NIL OR spaces[right]=NIL THEN NIL ELSE SingletonSpaces,
functional: [TRUE, TRUE],
mayDuplicate: FALSE,
mutability: constant,
data: NEW [SpacePair ← spaces]],
bkwdable: ALL[TRUE]];
};
singletonClass: PairCollClass ~ MakeSingletonClass[[NIL, NIL]];
singletonMap: ATOM ~ $PairCollectionsImplSingletonMap;
GetSingletonClass: PUBLIC PROC [spaces: SpacePair] RETURNS [class: PairCollClass] ~ {
IF spaces[left]=NIL OR spaces[right]=NIL THEN RETURN [singletonClass];
{map: Atom.PropList ← NARROW[List.Assoc[singletonMap, spaces[left].other]];
class ← NARROW[List.Assoc[spaces[right], map]];
IF class=NIL THEN {
class ← MakeSingletonClass[spaces];
map ← List.PutAssoc[spaces[right], class, map];
spaces[left].other ← List.PutAssoc[singletonMap, map, spaces[left].other];
};
RETURN}};
SingletonHasPair: PROC [pc: PairColl, pair: Pair] RETURNS [BOOL] ~ {
spaces: REF SpacePair ~ NARROW[pc.class.data];
elt: REF Pair ~ NARROW[pc.data];
IF spaces[left]=NIL OR spaces[right]=NIL THEN Cant[pc];
RETURN [
spaces[left].SpaceEqual[pair[left], elt[left]] AND
spaces[right].SpaceEqual[pair[right], elt[right]]];
};
ScanSingleton: PROC [pc: PairColl, Test: Tester, bkwd: BOOL] RETURNS [MaybePair] ~ {
rp: REF Pair ~ NARROW[pc.data];
RETURN [IF Test[rp^] THEN [TRUE, rp^] ELSE noMaybePair];
};
SingletonSize: PROC [pc: PairColl, limit: LNAT] RETURNS [LNAT] ~ {RETURN[1]};
SingletonSpaces: PROC [pc: PairColl] RETURNS [SpacePair] ~ {
spaces: REF SpacePair ~ NARROW[pc.class.data];
RETURN [spaces^]};
idClass: PairCollClass ~ CreateClass[
cp: [
HasPair: IDHasPair,
Image: IDImage,
Apply: IDApply,
ScanHalfRestriction: IDScanHalfRestriction,
ImageSize: IDImageSize,
Spaces: IDSpaces,
functional: [TRUE, TRUE],
mayDuplicate: FALSE,
mutability: constant],
dirable: [TRUE, TRUE]];
id: PUBLIC ConstPairColl ~ AsConst[[idClass, NIL]];
IDHasPair: PROC [pc: PairColl, pair: Pair] RETURNS [BOOL]
~ {RETURN [pair[left] = pair[right]]};
IDImage: PROC [pc: PairColl, coll: Collection, dir: Direction] RETURNS [UWColl]
~ {RETURN [coll.Insulate]};
IDApply: PROC [pc: PairColl, v: Value, dir: Direction] RETURNS [MaybeValue]
~ {RETURN [[TRUE, v]]};
IDScanHalfRestriction: PROC [pc: PairColl, side: Side, coll: Collection, Test: Tester, bkwd: BOOL] RETURNS [mp: MaybePair ← noMaybePair] ~ {
Pass: PROC [val: Value] RETURNS [pass: BOOLFALSE] ~ {
IF (pass ← Test[[val, val]]) THEN mp ← [TRUE, [val, val]];
RETURN};
[] ← coll.Scan[Pass];
RETURN};
IDImageSize: PROC [pc: PairColl, coll: Collection, dir: Direction, limit: LNAT] RETURNS [LNAT]
~ {RETURN [limit]};
IDSpaces: PROC [pc: PairColl] RETURNS [SpacePair]
~ {RETURN [[refs, refs]]};
listClasses: ARRAY --functional[leftToRight]--BOOL OF ARRAY --functional[rightToLeft]--BOOL OF ARRAY --mayDuplicate--BOOL OF PairCollClass;
Lyst: TYPE ~ REF LystPrivate;
LystPrivate: TYPE ~ RECORD [
size: LNAT ← 0,
spaces: SpacePair,
vals: LOP
];
CreateFromList: PUBLIC PROC [vals: LOP, functional: BoolPair ← [FALSE, FALSE], spaces: SpacePair ← [refs, refs], mayDuplicate: BOOLFALSE] RETURNS [ConstPairColl] ~ {
l: Lyst ~ NEW [LystPrivate ← [spaces: spaces, vals: vals]];
FOR vals ← vals, vals.rest WHILE vals#NIL DO l.size ← l.size+1 ENDLOOP;
RETURN AsConst[[listClasses[functional[leftToRight]][functional[rightToLeft]][mayDuplicate], l]];
};
LystHasPair: PROC [pc: PairColl, pair: Pair] RETURNS [BOOL] ~ {
l: Lyst ~ NARROW[pc.data];
FOR vals: LOP ← l.vals, vals.rest WHILE vals#NIL DO
IF l.spaces[left].SpaceEqual[pair[left], vals.first[left]] AND l.spaces[right].SpaceEqual[pair[right], vals.first[right]] THEN RETURN [TRUE];
ENDLOOP;
RETURN [FALSE]};
ScanLyst: PROC [pc:PairColl, Test:Tester, bkwd:BOOL] RETURNS [MaybePair] ~ {
l: Lyst ~ NARROW[pc.data];
FOR vals: LOP ← l.vals, vals.rest WHILE vals#NIL DO
IF Test[vals.first] THEN RETURN [[TRUE, vals.first]];
ENDLOOP;
RETURN [noMaybePair]};
LystSize: PROC [pc: PairColl, limit: LNAT] RETURNS [LNAT] ~ {
l: Lyst ~ NARROW[pc.data];
RETURN [l.size]};
LystSpaces: PROC [pc: PairColl] RETURNS [SpacePair] ~ {
l: Lyst ~ NARROW[pc.data];
RETURN [l.spaces]};
InverseClasses: TYPE ~ ARRAY --functional[leftToRight]--BOOL OF ARRAY --functional[rightToLeft]--BOOL OF ARRAY --mayDuplicate--BOOL OF ARRAY OrderStyle OF ARRAY Mutability OF PairCollClass;
inverseClasses: REF InverseClasses ~ NEW[InverseClasses];
Invert: PUBLIC PROC [pc: PairColl] RETURNS [PairColl] ~ {
IF
pc.data#NIL AND ISTYPE[pc.data, REF PairColl] AND
pc.class = inverseClasses
[pc.Functional[][leftToRight]]
[pc.Functional[][rightToLeft]]
[pc.MayDuplicate]
[pc.OrderStyleOf]
[pc.MutabilityOf]
THEN RETURN [DeRef[pc.data]];
RETURN [[
inverseClasses
[pc.Functional[][rightToLeft]]
[pc.Functional[][leftToRight]]
[pc.MayDuplicate]
[pc.OrderStyleOf]
[pc.MutabilityOf],
pc.Refify]];
};
InvertedPrimitive: PROC [pc: PairColl, op: ATOM, args: ArgList] RETURNS [PrimitiveAnswer] ~ {
subj: PairColl ~ DeRef[pc.data];
SELECT op FROM
$Widen => RETURN [no];
ENDCASE => NULL;
IF QualityOf[subj, op, InvertArgs[args]]=primitive THEN RETURN [yes];
RETURN [no];
};
InvertArgs: PROC [args: ArgList] RETURNS [ArgList] ~ {
IF args=NIL THEN RETURN [NIL];
RETURN [CONS[
SELECT args.first FROM
$TRUE => $FALSE,
$FALSE => $TRUE,
$left => $right,
$right => $left,
$leftToRight => $rightToLeft,
$rightToLeft => $leftToRight,
ENDCASE => ERROR,
InvertArgs[args.rest]
]];
};
InvertedHasPair: PROC [pc: PairColl, pair: Pair] RETURNS [BOOL] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.HasPair[InvertPair[pair]]};
InvertedImage: PROC [pc: PairColl, coll: Collection, dir: Direction] RETURNS [UWColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.Image[coll, OtherDirection[dir]]};
InvertedApply: PROC [pc: PairColl, v: Value, dir: Direction] RETURNS [MaybeValue] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.Apply[v, OtherDirection[dir]]};
InvertedScan: PROC [pc: PairColl, Test: Tester, bkwd: BOOL] RETURNS [MaybePair] ~ {
subj: PairColl ~ DeRef[pc.data];
Mid: PROC [pair: Pair] RETURNS [pass: BOOLFALSE] ~ {pass ← Test[InvertPair[pair]]};
RETURN subj.Scan[Mid, bkwd]};
InvertedScanHalfRestriction: PROC [pc: PairColl, side: Side, coll: Collection, Test: Tester, bkwd: BOOL] RETURNS [MaybePair] ~ {
subj: PairColl ~ DeRef[pc.data];
Mid: PROC [pair: Pair] RETURNS [pass: BOOLFALSE] ~ {pass ← Test[InvertPair[pair]]};
RETURN subj.ScanHalfRestriction[coll, Mid, OtherSide[side], bkwd]};
InvertedExtremum: PROC [pc: PairColl, bkwd, remove: BOOL] RETURNS [MaybePair] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.class.Extremum[subj, bkwd, remove].InvertMaybe};
InvertedGet3: PROC [pc: PairColl, pair: Pair] RETURNS [prev, same, next: MaybePair] ~ {
subj: PairColl ~ DeRef[pc.data];
[prev, same, next] ← subj.Get3[InvertPair[pair]];
prev.pair ← InvertPair[prev.pair];
same.pair ← InvertPair[same.pair];
next.pair ← InvertPair[next.pair];
RETURN};
InvertedSize: PROC [pc: PairColl, limit: LNAT] RETURNS [LNAT] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.Size[limit]};
InvertedImageSize: PROC [pc: PairColl, coll: Collection, dir: Direction, limit: LNAT] RETURNS [LNAT] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.ImageSize[coll, OtherDirection[dir], limit]};
InvertedCopy: PROC [pc: PairColl] RETURNS [VarPairColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [subj.Copy.Invert.AsVar]};
InvertedInsulate: PROC [pc: PairColl] RETURNS [UWPairColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [subj.Insulate.Invert.AsUW]};
InvertedValueOf: PROC [pc: PairColl] RETURNS [ConstPairColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [subj.ValueOf.Invert.AsConst]};
InvertedFreeze: PROC [pc: PairColl] RETURNS [ConstPairColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [subj.Freeze.Invert.AsConst]};
InvertedThaw: PROC [pc: PairColl] ~ {
subj: PairColl ~ DeRef[pc.data];
subj.Thaw[]; RETURN};
InvertedCollectionOn: PROC [pc: PairColl, side: Side] RETURNS [UWColl] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.CollectionOn[OtherSide[side]]};
InvertedCurSetOn: PROC [pc: PairColl, side: Side] RETURNS [ConstSet] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.CurSetOn[OtherSide[side]]};
InvertedAddColl: PROC [pc, other: PairColl, if: IfNewsPair, where: Where] RETURNS [some: NewsSetPair] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [InvertNewsSetPair[subj.AddColl[other.Invert, InvertIfNewsPair[if], where.InvertWhere]]];
};
InvertedRemColl: PROC [pc, other: PairColl, style: RemoveStyle] RETURNS [hadSome, hadAll: BoolPair] ~ {
subj: PairColl ~ DeRef[pc.data];
[hadSome, hadAll] ← subj.RemColl[other.Invert, style];
hadSome ← InvertBoolPair[hadSome];
hadAll ← InvertBoolPair[hadAll];
};
InvertedDeleteColl: PROC [pc: PairColl, coll: Collection, side: Side, style: RemoveStyle] RETURNS [hadSome, hadAll: BOOL] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.DeleteColl[coll, OtherSide[side], style]};
InvertedQuaIntFn: PROC [pc: PairColl, dir: Direction] RETURNS [MaybeValue] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN subj.QuaIntFn[OtherDirection[dir]]};
InvertedSpaces: PROC [pc: PairColl] RETURNS [SpacePair] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [InvertSpacePair[subj.Spaces]]};
InvertedOrderingOf: PROC [pc: PairColl] RETURNS [Ordering] ~ {
subj: PairColl ~ DeRef[pc.data];
RETURN [subj.OrderingOf.InvertOrdering]};
InvertOrdering: PUBLIC PROC [o: Ordering] RETURNS [io: Ordering] ~ {
RETURN [[CompareInversion, NEW [Ordering ← o], InvertSideCare[o.sideCare]]];
};
CompareInversion: PROC [data: REF ANY, elt1, elt2: Pair] RETURNS [Basics.Comparison] --PairCompareProc-- ~ {
o: REF Ordering ~ NARROW[data];
RETURN [o.Compare[o.data, InvertPair[elt1], InvertPair[elt2]]]};
Composition: TYPE ~ REF CompositionPrivate;
CompositionPrivate: TYPE ~ RECORD [
cs: ARRAY Side OF PairColl,
restricts: ARRAY Side OF BOOL,
scanSide, sizeSide: Side
];
Compose: PUBLIC PROC [pcs: ARRAY Side OF PairColl, restricts: ARRAY Side OF BOOL ← [TRUE, TRUE]] RETURNS [PairColl] ~ {
functional: BoolPair;
FOR dir: Direction IN Direction DO
functional[dir] ← pcs[left].Functional[][dir] AND pcs[right].Functional[][dir];
ENDLOOP;
{sq: ARRAY Side OF ImplQuality ~ [
QMin[
QMin[goodDefault,
QMin[
QualityOf[pcs[left], $Scan, LIST[$FALSE]],
QualityOf[pcs[right], $ScanMapping, LIST[$leftToRight, $FALSE]]]],
QMin[goodDefault,
QMin[
QualityOf[pcs[left], $Scan, LIST[$TRUE]],
QualityOf[pcs[right], $ScanMapping, LIST[$leftToRight, $TRUE]]]]],
QMin[
QMin[goodDefault,
QMin[
QualityOf[pcs[right], $Scan, LIST[$FALSE]],
QualityOf[pcs[left], $ScanMapping, LIST[$rightToLeft, $FALSE]]]],
QMin[goodDefault,
QMin[
QualityOf[pcs[right], $Scan, LIST[$TRUE]],
QualityOf[pcs[left], $ScanMapping, LIST[$rightToLeft, $TRUE]]]]]];
scanSide: Side ~ IF sq[right]>sq[left] THEN right ELSE IF sq[left]>sq[right] THEN left ELSE IF functional[rightToLeft] AND NOT functional[leftToRight] THEN right ELSE left;
restricted: BOOL ~ restricts[OtherSide[scanSide]];
canSizeLeft: BOOL ~ pcs[left].Functional[][rightToLeft] AND NOT restricts[left];
canSizeRight: BOOL ~ pcs[right].Functional[][leftToRight] AND NOT restricts[right];
sizeSide: Side ~ IF canSizeLeft THEN left ELSE right;
scanDir: Direction ~ From[scanSide];
outer: PairColl ~ IF scanSide=left THEN pcs[left] ELSE pcs[right];
orderStyle: OrderStyle ~ SELECT outer.OrderStyleOf FROM
none => none,
value => IF functional[scanDir] AND NOT outer.OrderingOf[].sideCare.CaresAbout[OtherSide[scanSide]] THEN value ELSE none,
client => IF functional[scanDir] THEN client ELSE none,
ENDCASE => ERROR;
mayDuplicate: BOOL ~ pcs[left].MayDuplicate OR pcs[right].MayDuplicate OR NOT (pcs[left].Functional[][leftToRight] OR pcs[right].Functional[][rightToLeft]);
mayChange: BOOL ~ pcs[left].MutabilityOf#constant OR pcs[right].MutabilityOf#constant;
c: Composition ~ NEW [CompositionPrivate ← [pcs, restricts, scanSide, sizeSide]];
RETURN [[
composedClasses
[functional[leftToRight]]
[functional[rightToLeft]]
[mayDuplicate]
[orderStyle]
[IF mayChange THEN readonly ELSE constant]
[restricted]
[canSizeLeft OR canSizeRight],
c]];
}};
ComposedClasses: TYPE ~ ARRAY --functional[leftToRight]--BOOL OF ARRAY --functional[rightToLeft]--BOOL OF ARRAY --mayDuplicate--BOOL OF ARRAY OrderStyle OF ARRAY UnwriteableMutability OF ARRAY --restricted--BOOL OF ARRAY --canSize--BOOL OF PairCollClass;
composedClasses: REF ComposedClasses ~ NEW[ComposedClasses];
CompositionPrimitive: PROC [pc: PairColl, op: ATOM, args: ArgList] RETURNS [PrimitiveAnswer] ~ {
c: Composition ~ NARROW[pc.data];
SELECT op FROM
$Image => RETURN [IF c.cs[left].QualityOf[op, args]>=goodDefault AND c.cs[right].QualityOf[op, args]>=goodDefault THEN yes ELSE no];
$ImageSize => {dir: Direction ~ GetDir[args, 1];
RETURN [IF c.cs[Source[dir]].QualityOf[$Image, args]>=goodDefault AND c.cs[Dest[dir]].QualityOf[$ImageSize, args]>=goodDefault THEN yes ELSE no]};
$CollectionOn, $CurSetOn => {side: Side ~ GetSide[args, 1];
RETURN [IF c.restricts[OtherSide[side]] OR c.cs[side].QualityOf[op, args]<goodDefault THEN no ELSE yes]};
$ScanHalfRestriction => {
side: Side ~ GetSide[args, 1];
bkwd: BOOL ~ GetBool[args, 2];
otherSide: Side ~ OtherSide[side];
q1: ImplQuality ~ c.cs[side].QualityOf[$ScanHalfRestriction, args];
q2: ImplQuality ~ c.cs[otherSide].QualityOf[$ScanMapping, LIST[FromDir[From[side]], FromBool[bkwd]]];
RETURN [IF (q1>=goodDefault OR q2>=goodDefault) AND (pc.Functional[][From[side]] OR pc.MayDuplicate) THEN yes ELSE pass];
};
ENDCASE => RETURN [pass];
};
CompositionHasPair: PROC [pc: PairColl, pair: Pair] RETURNS [has: BOOL] ~ {
c: Composition ~ NARROW[pc.data];
q: ARRAY Side OF ImplQuality ~ [
QMin[QualityOf[c.cs[left], $ScanMapping, LIST[$leftToRight]], QualityOf[c.cs[right], $HasPair]],
QMin[QualityOf[c.cs[right], $ScanMapping, LIST[$rightToLeft]], QualityOf[c.cs[left], $HasPair]]];
s: Side ~ IF q[right]>q[left] THEN right ELSE left;
os: Side ~ OtherSide[s];
PerMap: PROC [val: Value] RETURNS [pass: BOOLFALSE] ~ {
pass ← c.cs[os].HasPair[ConsPair[s, val, pair[os]]];
RETURN};
has ← c.cs[s].ScanMapping[pair[s], PerMap, From[s]].found;
RETURN};
CompositionImage: PROC [pc: PairColl, coll: Collection, dir: Direction] RETURNS [UWColl] ~ {
c: Composition ~ NARROW[pc.data];
RETURN c.cs[Dest[dir]].Image[c.cs[Source[dir]].Image[coll, dir], dir]};
CompositionApply: PROC [pc: PairColl, v: Value, dir: Direction] RETURNS [mv: MaybeValue] ~ {
c: Composition ~ NARROW[pc.data];
mv ← c.cs[Source[dir]].Apply[v, dir];
IF NOT mv.found THEN RETURN [noMaybe];
mv ← c.cs[Dest[dir]].Apply[mv.val, dir];
RETURN};
CompositionScan: PROC [pc: PairColl, Test: Tester, bkwd: BOOL] RETURNS [mp: MaybePair] ~ {
c: Composition ~ NARROW[pc.data];
s: Side ~ c.scanSide;
os: Side ~ OtherSide[s];
Outer: PROC [pair: Pair] RETURNS [pass: BOOLFALSE] ~ {
test: Pair ← ALL[pair[s]];
Inner: PROC [val: Value] RETURNS [pass: BOOLFALSE] ~ {
test[os] ← val;
IF (pass ← Test[test]) THEN mp ← [TRUE, test];
RETURN};
pass ← c.cs[os].ScanMapping[pair[os], Inner, From[s], bkwd].found;
RETURN};
[] ← c.cs[s].Scan[Outer, bkwd];
RETURN};
CompositionScanHalfRestriction: PROC [pc: PairColl, side: Side, coll: Collection, Test: Tester, bkwd: BOOL] RETURNS [mp: MaybePair] ~ {
c: Composition ~ NARROW[pc.data];
otherSide: Side ~ OtherSide[side];
CollOuter: PROC ~ {
Outer: PROC [pair: Pair] RETURNS [pass: BOOL] ~ {
test: Pair ← ALL[pair[side]];
Inner: PROC [val: Value] RETURNS [pass: BOOL] ~ {
test[otherSide] ← val;
IF (pass ← Test[test]) THEN mp ← [TRUE, test];
RETURN};
pass ← c.cs[otherSide].ScanMapping[pair[otherSide], Inner, From[side], bkwd].found;
RETURN};
[] ← c.cs[side].ScanHalfRestriction[coll, Outer, side, bkwd];
RETURN};
q1: ImplQuality ~ c.cs[side].QualityOf[$ScanHalfRestriction, LIST[FromSide[side], FromBool[bkwd]]];
q2: ImplQuality ~ c.cs[otherSide].QualityOf[$ScanMapping, LIST[FromDir[From[side]], FromBool[bkwd]]];
IF (q1>=goodDefault OR q2>=goodDefault) AND (pc.Functional[][From[side]] OR pc.MayDuplicate) THEN CollOuter[] ELSE mp ← DefaultScanHalfRestriction[pc, side, coll, Test, bkwd];
RETURN};
Complete: PROC [c: Composition, mp: MaybePair] RETURNS [MaybePair] ~ {
IF NOT mp.found THEN RETURN [mp];
mp.pair[right] ← c.cs[OtherSide[c.scanSide]].Apply[mp.pair[right], From[c.scanSide]].Val;
RETURN [mp]};
CompositionExtremum: PROC [pc: PairColl, bkwd, remove: BOOL] RETURNS [MaybePair] ~ {
c: Composition ~ NARROW[pc.data];
IF remove THEN pc.Complain[notVariable];
RETURN Complete[c, c.cs[c.scanSide].Extremum[bkwd, remove]]};
CompositionGet3: PROC [pc: PairColl, pair: Pair] RETURNS [prev, same, next: MaybePair] ~ {
c: Composition ~ NARROW[pc.data];
[prev, same, next] ← c.cs[c.scanSide].Get3[pair];
prev ← Complete[c, prev];
same ← Complete[c, same];
next ← Complete[c, next];
RETURN};
CompositionSize: PROC [pc: PairColl, limit: LNAT] RETURNS [LNAT] ~ {
c: Composition ~ NARROW[pc.data];
RETURN c.cs[c.sizeSide].Size[limit]};
CompositionImageSize: PROC [pc: PairColl, coll: Collection, dir: Direction, limit: LNAT] RETURNS [LNAT] ~ {
c: Composition ~ NARROW[pc.data];
RETURN c.cs[Dest[dir]].ImageSize[c.cs[Source[dir]].Image[coll, dir], dir, limit]};
CompositionValueOf: PROC [pc: PairColl] RETURNS [ConstPairColl] ~ {
c: Composition ~ NARROW[pc.data];
RETURN [Compose[[c.cs[left].ValueOf[], c.cs[right].ValueOf[]]].AsConst]};
CompositionCollectionOn: PROC [pc: PairColl, side: Side] RETURNS [UWColl] ~ {
c: Composition ~ NARROW[pc.data];
IF NOT c.restricts[OtherSide[side]] THEN RETURN c.cs[side].CollectionOn[side];
RETURN DefaultCollectionOn[pc, side]};
CompositionCurSetOn: PROC [pc: PairColl, side: Side] RETURNS [ConstSet] ~ {
c: Composition ~ NARROW[pc.data];
IF NOT c.restricts[OtherSide[side]] THEN RETURN c.cs[side].CurSetOn[side];
RETURN DefaultCurSetOn[pc, side]};
CompositionQuaIntFn: PROC [pc: PairColl, dir: Direction] RETURNS [MaybeValue] ~ {
c: Composition ~ NARROW[pc.data];
IF NOT pc.Functional[][dir] THEN RETURN [noMaybe];
{mv: MaybeValue ~ c.cs[Source[dir]].QuaIntFn[dir];
IF NOT mv.found THEN RETURN [noMaybe];
{if1: IntFns.IntFn ~ IntFns.DeRef[mv.val];
rt: PairColl ~ IF dir=rightToLeft THEN c.cs[Dest[dir]].Invert ELSE c.cs[Dest[dir]];
RETURN [[TRUE, if1.Compose[right: rt, leftRestricts: c.restricts[Source[dir]], rightRestricts: c.restricts[Dest[dir]]].Refify]]}}};
CompositionSpaces: PROC [pc: PairColl] RETURNS [sp: SpacePair] ~ {
c: Composition ~ NARROW[pc.data];
sp[left] ← c.cs[left].Spaces[][left];
sp[right] ← c.cs[right].Spaces[][right];
RETURN};
CompositionOrderingOf: PROC [pc: PairColl] RETURNS [Ordering] ~ {
c: Composition ~ NARROW[pc.data];
scanSide: Side ~ c.scanSide;
outer: PairColl ~ c.cs[scanSide];
RETURN outer.OrderingOf[];
};
BeRope: PROC [r: ROPE] RETURNS [ROPE] ~ INLINE {RETURN[r]};
Start: PROC ~ {
FOR lr: BOOL IN BOOL DO FOR rl: BOOL IN BOOL DO FOR mayDuplicate: BOOL IN BOOL DO
listClasses[lr][rl][mayDuplicate] ← CreateClass[[
HasPair: LystHasPair,
Scan: ScanLyst,
Size: LystSize,
Spaces: LystSpaces,
functional: [lr, rl],
mayDuplicate: mayDuplicate,
orderStyle: none,
mutability: constant]];
FOR orderStyle: OrderStyle IN OrderStyle DO FOR mutability: Mutability IN Mutability DO
inverseClasses[lr][rl][mayDuplicate][orderStyle][mutability] ← CreateClass[[
Primitive: InvertedPrimitive,
HasPair: InvertedHasPair,
Image: InvertedImage,
Apply: InvertedApply,
Scan: InvertedScan,
ScanHalfRestriction: InvertedScanHalfRestriction,
Extremum: InvertedExtremum,
Get3: InvertedGet3,
Size: InvertedSize,
ImageSize: InvertedImageSize,
Copy: InvertedCopy,
Insulate: InvertedInsulate,
ValueOf: InvertedValueOf,
Freeze: InvertedFreeze,
Thaw: InvertedThaw,
CollectionOn: InvertedCollectionOn,
CurSetOn: InvertedCurSetOn,
AddColl: InvertedAddColl,
RemColl: InvertedRemColl,
DeleteColl: InvertedDeleteColl,
QuaIntFn: InvertedQuaIntFn,
Spaces: InvertedSpaces,
OrderingOf: InvertedOrderingOf,
functional: [lr, rl],
mayDuplicate: mayDuplicate,
orderStyle: orderStyle,
mutability: mutability]];
IF mutability#variable THEN FOR restricted: BOOL IN BOOL DO FOR canSize: BOOL IN BOOL DO
composedClasses[lr][rl][mayDuplicate][orderStyle][mutability][restricted][canSize] ← CreateClass[[
Primitive: CompositionPrimitive,
HasPair: CompositionHasPair,
Image: CompositionImage,
Apply: CompositionApply,
Scan: CompositionScan,
ScanHalfRestriction: CompositionScanHalfRestriction,
Extremum: IF NOT restricted THEN CompositionExtremum ELSE NIL,
Get3: IF NOT restricted THEN CompositionGet3 ELSE NIL,
Size: IF canSize THEN CompositionSize ELSE NIL,
ImageSize: CompositionImageSize,
ValueOf: CompositionValueOf,
CollectionOn: CompositionCollectionOn,
CurSetOn: CompositionCurSetOn,
QuaIntFn: CompositionQuaIntFn,
Spaces: CompositionSpaces,
OrderingOf: IF orderStyle=value THEN CompositionOrderingOf ELSE NIL,
functional: [lr, rl],
mayDuplicate: mayDuplicate,
orderStyle: orderStyle,
mutability: mutability]];
ENDLOOP ENDLOOP;
ENDLOOP ENDLOOP;
ENDLOOP ENDLOOP ENDLOOP;
};
Start[];
END.