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:
BOOL ←
FALSE] ~ {
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:
BOOL ←
FALSE]
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: BOOL ← FALSE] ~ {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: BOOL ← FALSE] ~ {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:
BOOL ←
FALSE] ~ {
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:
BOOL ←
FALSE] ~ {
test: Pair ← ALL[pair[s]];
Inner:
PROC [val: Value]
RETURNS [pass:
BOOL ←
FALSE] ~ {
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.