Operations on PairColls
Cant:
ERROR [pc: PairColl];
Raised when a pair collection is asked to perform an operation it can't.
QualityOf:
PROC [pc: PairColl, op:
ATOM, args: ArgList ←
NIL]
RETURNS [ImplQuality];
Use this to investigate what operations a collection supports, and how well it does so. The quality depends on the collection, the operation, and certain arguments. Those arguments are the Direction, or the Side, or the bkwds: BOOL, if any. They are indicated to QualityOf as a LIST OF REF ANY, where each REF ANY is an ATOM whose name is the name of the enumerated value (e.g., $leftToRight, $FALSE). The op is the name of a procedure in this interface (other than QualityOf and derivatives) that calls class procedures.
Can:
PROC [pc: PairColl, op:
ATOM, args: ArgList ←
NIL]
RETURNS [
BOOL]
~ INLINE {RETURN [QualityOf[pc, op, args]#cant]};
Widen:
PROC [pc: PairColl]
RETURNS [Collection
--of REF Pair--]
~ INLINE {RETURN pc.class.Widen[pc]};
HasPair:
PROC [pc: PairColl, pair: Pair]
RETURNS [
BOOL]
~ INLINE {RETURN pc.class.HasPair[pc, pair]};
OrderStyleOf:
PROC [pc: PairColl]
RETURNS [OrderStyle]
~ INLINE {RETURN [pc.class.orderStyle]};
Ordering: TYPE ~ RECORD [Compare: PairCompareProc, data: REF ANY, sideCare: SideCare];
PairCompareProc: TYPE ~ PROC [data: REF ANY, elt1, elt2: Pair] RETURNS [Basics.Comparison];
SideCare: TYPE ~ {neither, left, right, both};
unordered: Ordering ~ [NIL, NIL, neither];
OrderBySide: PROC [side: Side, o: Colls.Ordering] RETURNS [Ordering];
OrderByBoth: PROC [highSide: Side, high, low: Colls.Ordering] RETURNS [Ordering];
OrderingOf:
PROC [pc: PairColl]
RETURNS [Ordering]
~ INLINE {RETURN pc.class.OrderingOf[pc]};
CaresAbout:
PROC [sideCare: SideCare, side: Side]
RETURNS [
BOOL]
~
INLINE {
RETURN [
SELECT sideCare
FROM
neither => FALSE,
left => side=left,
right => side=right,
both => TRUE,
ENDCASE => ERROR]};
Image:
PROC [pc: PairColl, coll: Collection, dir: Direction ← leftToRight]
RETURNS [UWColl]
For leftToRight, the result is the things that are on the right sides of pairs in pc that have an element of coll on their left side. The result tracks changes to the PairColl, but may not be changed directly.
~ INLINE {RETURN pc.class.Image[pc, coll, dir]};
Mapping:
PROC [pc: PairColl, v: Value, dir: Direction ← leftToRight]
RETURNS [UWColl]
The image of a singleton.
~ INLINE {RETURN pc.class.Image[pc, Colls.CreateSingleton[v, pc.Spaces[][Source[dir]]], dir]};
Enumerate: PROC [pc: PairColl, Consume: PROC [Pair], bkwd: BOOL ← FALSE];
MaybePair: TYPE ~ RECORD [found: BOOL, pair: Pair];
noMaybePair: READONLY MaybePair -- = [FALSE, noPair] --;
ParallelFind: TYPE ~ RECORD [found: BOOL, a, b: MaybePair];
Tester: TYPE ~ PROC [pair: Pair] RETURNS [pass: BOOL ← FALSE];
Scan:
PROC [pc: PairColl,
Test: Tester, bkwd:
BOOL ←
FALSE]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.Scan[pc, Test, bkwd]};
EnumerateImage: PROC [pc: PairColl, coll: Collection, Consume: PROC [Value], dir: Direction ← leftToRight, bkwd: BOOL ← FALSE];
EnumerateMapping:
PROC [pc: PairColl, v: Value,
Consume:
PROC [Value], dir: Direction ← leftToRight, bkwd:
BOOL ←
FALSE]
~ INLINE {EnumerateImage[pc, Colls.CreateSingleton[v, pc.Spaces[][Source[dir]]], Consume, dir, bkwd]};
EnumerateHalfRestriction:
PROC [pc: PairColl, coll: Collection,
Consume:
PROC [Pair], side: Side ← left, bkwd:
BOOL ←
FALSE];
Enumerates those pairs such that pair[side] is in coll.
ScanImage: PROC [pc: PairColl, coll: Collection, Test: Colls.Tester, dir: Direction ← leftToRight, bkwd: BOOL ← FALSE] RETURNS [MaybePair];
ScanMapping:
PROC [pc: PairColl, v: Value,
Test: Colls.Tester, dir: Direction ← leftToRight, bkwd:
BOOL ←
FALSE]
RETURNS [MaybePair]
~ INLINE {RETURN ScanImage[pc, Colls.CreateSingleton[v, pc.Spaces[][Source[dir]]], Test, dir, bkwd]};
ScanHalfRestriction:
PROC [pc: PairColl, coll: Collection,
Test: Tester, side: Side ← left, bkwd:
BOOL ←
FALSE]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.ScanHalfRestriction[pc, side, coll, Test, bkwd]};
ParallelTester: TYPE ~ PROC [a, b: MaybePair] RETURNS [pass: BOOL ← FALSE];
ParallelScan:
PROC [a, b: PairColl,
Test: ParallelTester, bkwd:
BOOL ←
FALSE]
RETURNS [ParallelFind]
~ INLINE {RETURN ParallelScanHalfRestriction[a, b, passAll, Test, left, bkwd]};
ParallelScanHalfRestriction: PROC [a, b: PairColl, coll: Collection, Test: ParallelTester, side: Side ← left, bkwd: BOOL ← FALSE] RETURNS [ParallelFind];
First:
PROC [pc: PairColl]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.Extremum[pc, FALSE, FALSE]};
Last:
PROC [pc: PairColl]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.Extremum[pc, TRUE, FALSE]};
Pop:
PROC [pc: PairColl, bkwd:
BOOL ←
FALSE]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.Extremum[pc, bkwd, TRUE]};
Extremum:
PROC [pc: PairColl, bkwd, remove:
BOOL]
RETURNS [MaybePair]
~ INLINE {RETURN pc.class.Extremum[pc, bkwd, remove]};
Next:
PROC [pc: PairColl, pair: Pair]
RETURNS [MaybePair]
~ INLINE {RETURN [pc.class.Get3[pc, pair].next]};
Prev:
PROC [pc: PairColl, pair: Pair]
RETURNS [MaybePair]
~ INLINE {RETURN [pc.class.Get3[pc, pair].prev]};
Get3:
PROC [pc: PairColl, pair: Pair]
RETURNS [prev, same, next: MaybePair]
~ INLINE {RETURN pc.class.Get3[pc, pair]};
Size:
PROC [pc: PairColl, limit:
LNAT ←
LNAT.
LAST]
RETURNS [
LNAT]
~ INLINE {RETURN [pc.class.Size[pc, limit]]};
Empty:
PROC [pc: PairColl]
RETURNS [
BOOL]
~ INLINE {RETURN [pc.class.Size[pc, 1]=0]};
ImageSize:
PROC [pc: PairColl, coll: Collection, dir: Direction ← leftToRight, limit:
LNAT ←
LNAT.
LAST]
RETURNS [
LNAT]
~ INLINE {RETURN [pc.class.ImageSize[pc, coll, dir, limit]]};
MappingSize:
PROC [pc: PairColl, v: Value, dir: Direction ← leftToRight, limit:
LNAT ←
LNAT.
LAST]
RETURNS [
LNAT]
~ INLINE {RETURN [pc.class.ImageSize[pc, Colls.CreateSingleton[v, pc.Spaces[][Source[dir]]], dir, limit]]};
MutabilityOf:
PROC [pc: PairColl]
RETURNS [Mutability]
~ INLINE {RETURN [pc.class.mutability]};
Copy:
PROC [pc: PairColl]
RETURNS [VarPairColl]
~ INLINE {RETURN pc.class.Copy[pc]};
Insulate:
PROC [pc: PairColl]
RETURNS [UWPairColl]
~ INLINE {RETURN pc.class.Insulate[pc]};
ValueOf:
PROC [pc: PairColl]
RETURNS [ConstPairColl]
~ INLINE {RETURN pc.class.ValueOf[pc]};
Freeze:
PROC [pc: PairColl]
RETURNS [const: ConstPairColl]
~ INLINE {RETURN pc.class.Freeze[pc]};
Thaw:
PROC [pc: PairColl]
~ INLINE {pc.class.Thaw[pc]};
Where:
TYPE ~
RECORD [
SELECT kind: WhereKind
FROM
any => [],
end => [end: End],
rel => [pair: Pair, reln: WhereReln],
ENDCASE ← any[]];
News: TYPE ~ {same, different, new};
NewsPair: TYPE ~ PACKED ARRAY Direction OF News;
NewsSetPair:
TYPE ~
ARRAY Direction
OF
PACKED
ARRAY News
OF
BOOL;
When adding a pair to a variable collection that is Functional[dir], the resultant NewsPair[dir] tells about the previous state of that variable: new means there was previously no pair with equivalent [Source[dir]]; different means there was a pair with equivalent [Source[dir]] and non-equivalent [Dest[dir]]; same means there was previously an equivalent pair. If the collection is not Functional[dir], the resultant NewsPair[dir] can be anything.
IfNews: TYPE ~ PACKED ARRAY --news=new--BOOL OF --add:--BOOL;
IfNewsPair:
TYPE ~
ARRAY Direction
OF IfNews;
The procedures that add to variable pair collections can be conditional on the previous state: if the collection is Functional[dir], if[dir][news[dir]=new] must be TRUE in order for the addition to happen.
alwaysAdd: IfNewsPair ~ ALL[ALL[TRUE]];
addIfNew: IfNewsPair ~ ALL[[FALSE, TRUE]];
addIfOld: IfNewsPair ~ ALL[[TRUE, FALSE]];
AddPair: PROC [pc: PairColl, pair: Pair, if: IfNewsPair ← alwaysAdd, where: Where ← []] RETURNS [news: NewsPair];
AddNewPair:
PROC [pc: PairColl, pair: Pair, where: Where ← []];
Like AddPair, with the expectation that the pair is new.
AddColl:
PROC [pc, other: PairColl, if: IfNewsPair ← alwaysAdd, where: Where ← []]
RETURNS [some: NewsSetPair]
Equivalent to a series of AddPairs. some[n][dir] iff some AddPair[..][dir]=n.
~ INLINE {RETURN pc.class.AddColl[pc, other, if, where]};
AddNewColl:
PROC [pc, other: PairColl, where: Where ← []];
Same as AddColl[if: addIfNew], and then in functional directions d insist that some[d][same] = some[d][different] = FALSE.
RemPair:
PROC [pc: PairColl, pair: Pair, style: RemoveStyle ← any]
RETURNS [hadMapping: BoolPair]
For collections that are Functional[dir]: hadMapping[dir] tells whether there was a pair with an equivalent Value on the Source[dir] side; for those not functional, hadMapping[dir] is unrestricted.
~ INLINE {RETURN [pc.class.RemColl[pc, CreateSingleton[pair, pc.Spaces[]], style].hadAll]};
RemColl:
PROC [pc, other: PairColl, style: RemoveStyle ← any]
RETURNS [hadSome, hadAll: BoolPair]
Equivalent to a bunch of RemPairs. hadSome[dir] is the OR of the hadMapping[dir]s, and hadAll[dir] is the AND.
~ INLINE {RETURN pc.class.RemColl[pc, other, style]};
Delete:
PROC [pc: PairColl, val: Value, side: Side ← left, style: RemoveStyle ← all]
RETURNS [hadSome:
BOOL]
Remove pair(s) with equivalent values on the given side. hadSome tells whether there were any.
~ INLINE {RETURN [pc.class.DeleteColl[pc, Colls.CreateSingleton[val, pc.Spaces[][side]], side, style].hadSome]};
DeleteColl:
PROC [pc: PairColl, coll: Collection, side: Side ← left, style: RemoveStyle ← all]
RETURNS [hadSome, hadAll:
BOOL]
~ INLINE {RETURN pc.class.DeleteColl[pc, coll, side, style]};
Spaces:
PROC [pc: PairColl]
RETURNS [SpacePair]
A PairColl must know the space on either side if it's functional in either direction.
~ INLINE {RETURN pc.class.Spaces[pc]};
CollectionOn:
PROC [pc: PairColl, side: Side]
RETURNS [UWColl]
Returns a collection of the elements on the given side of the pairs of pc. Result tracks changes to pc.
~ INLINE {RETURN [pc.class.CollectionOn[pc, side]]};
CurSetOn:
PROC [pc: PairColl, side: Side]
RETURNS [ConstSet]
Returns the current value, and thus does not track changes to pc.
~ INLINE {RETURN [[pc.class.CurSetOn[pc, side]]]};
Functional:
PROC [pc: PairColl]
RETURNS [BoolPair]
Functional[pc][leftToRight] => pc can't have two pairs with equivalent left Values and non-equivalent right Values.
~ INLINE {RETURN [pc.class.functional]};
MayDuplicate:
PROC [pc: PairColl]
RETURNS [
BOOL]
Might this relation enumerate equivalent pairs (or mappings) more than once?
~ INLINE {RETURN [pc.class.mayDuplicate]};
refPairColls: READONLY Space;
Equal:
PROC [a, b: PairColl, bounds: CollPair ← [passAll, passAll]]
RETURNS [
BOOL];